From c90a7839258e01c77e71be3adb9998a8ed06f3f0 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Thu, 22 Oct 2020 20:47:04 +0200 Subject: [PATCH] [IMP] kpi_dashboard: black, isort, prettier --- kpi_dashboard/demo/demo_dashboard.xml | 85 ++++----- kpi_dashboard/models/kpi_dashboard.py | 95 +++++---- kpi_dashboard/models/kpi_kpi.py | 148 +++++++------- kpi_dashboard/security/security.xml | 18 +- .../static/src/js/dashboard_controller.js | 147 +++++++------- .../static/src/js/dashboard_model.js | 18 +- .../static/src/js/dashboard_renderer.js | 117 ++++++------ kpi_dashboard/static/src/js/dashboard_view.js | 36 ++-- kpi_dashboard/static/src/js/field_widget.js | 69 +++---- .../static/src/js/widget/abstract_widget.js | 88 +++++---- .../static/src/js/widget/counter_widget.js | 10 +- .../static/src/js/widget/graph_widget.js | 91 +++++---- .../static/src/js/widget/integer_widget.js | 57 +++--- .../static/src/js/widget/meter_widget.js | 33 ++-- .../static/src/js/widget/number_widget.js | 17 +- .../static/src/js/widget/text_widget.js | 13 +- .../static/src/js/widget_registry.js | 4 +- .../static/src/scss/kpi_dashboard.scss | 42 ++-- kpi_dashboard/static/src/xml/dashboard.xml | 51 +++-- kpi_dashboard/templates/assets.xml | 86 ++++++--- kpi_dashboard/tests/test_formula.py | 24 +-- kpi_dashboard/tests/test_kpi_dashboard.py | 176 ++++++++--------- kpi_dashboard/views/kpi_dashboard.xml | 155 ++++++++------- kpi_dashboard/views/kpi_kpi.xml | 180 +++++++++++------- kpi_dashboard/views/kpi_menu.xml | 15 +- kpi_dashboard/wizards/kpi_dashboard_menu.xml | 25 +-- 26 files changed, 955 insertions(+), 845 deletions(-) diff --git a/kpi_dashboard/demo/demo_dashboard.xml b/kpi_dashboard/demo/demo_dashboard.xml index 3a31344c..83aa515a 100644 --- a/kpi_dashboard/demo/demo_dashboard.xml +++ b/kpi_dashboard/demo/demo_dashboard.xml @@ -8,7 +8,6 @@ #020202 30 - Number 01 $ @@ -18,7 +17,6 @@ result = {"value": 10000,"previous": 12000} - Number 02 @@ -28,10 +26,11 @@ result = {"value": 10000,"previous": 12000} result = {"value": 12000,"previous": 10000} - - - + Meter 01 @@ -41,7 +40,6 @@ result = {"value": 12000,"previous": 10000} result = {"min": 0, "max": 100, "value": 90} - Meter 02 $ @@ -51,10 +49,11 @@ result = {"min": 0, "max": 100, "value": 90} result = {"min": 0, "max": 100, "value": 40} - - - + Graph code @@ -84,125 +83,116 @@ result = {"graphs": [ ]} - - - + Integer counter code integer - + result = {"value": self.env.context.get('counter', 990)} - Counter code counter - + result = {"value": self.env.context.get('counter', 990)} - Dashboard title - + 1 1 4 #707070 #000000 - Number 01 - - + + 1 2 4 #47bbb3 #ffffff - Number 02 - - + + 1 6 4 #ec663c #ffffff - Meter 01 - - + + 2 2 4 #9c4274 #ffffff - Meter 02 - - + + 2 6 4 #12b0c5 #ffffff - +1 to Counter - + 3 10 1 2 #B41F1F #EEBF77 - - {'counter': (context.counter or 990) + 1} - - check_if(((context.counter or 990) + 1) % 2, '#ff0000', '#00ff00') + + {'counter': (context.counter or 990) + 1} + + check_if(((context.counter or 990) + 1) % 2, '#ff0000', '#00ff00') - Counter - - + + 3 11 3 #4B0082 #ffffff - Integer - - + + 4 11 3 #ffffff #4B0082 - Graph - - + + 3 2 2 @@ -210,5 +200,4 @@ result = {"value": self.env.context.get('counter', 990)} #ff9618 #ffffff - diff --git a/kpi_dashboard/models/kpi_dashboard.py b/kpi_dashboard/models/kpi_dashboard.py index 24d42301..c03073ab 100644 --- a/kpi_dashboard/models/kpi_dashboard.py +++ b/kpi_dashboard/models/kpi_dashboard.py @@ -1,7 +1,7 @@ # Copyright 2020 Creu Blanca # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -17,8 +17,7 @@ class KpiDashboard(models.Model): ) number_of_columns = fields.Integer(default=5, required=True) compute_on_fly_refresh = fields.Integer( - default=0, - help="Seconds to refresh on fly elements" + default=0, help="Seconds to refresh on fly elements" ) width = fields.Integer(compute="_compute_width") margin_y = fields.Integer(default=10, required=True) @@ -34,9 +33,7 @@ class KpiDashboard(models.Model): if "group_ids" in vals: for rec in self: if rec.menu_id: - rec.menu_id.write( - {"groups_id": [(6, 0, rec.group_ids.ids)]} - ) + rec.menu_id.write({"groups_id": [(6, 0, rec.group_ids.ids)]}) return res @api.depends("widget_dimension_x", "margin_x", "number_of_columns") @@ -78,7 +75,7 @@ class KpiDashboard(models.Model): return { "parent_id": menu.id or False, "name": self.name, - "action": "%s,%s" % (action._name, action.id), + "action": "{},{}".format(action._name, action.id), "groups_id": [(6, 0, self.group_ids.ids)], } @@ -106,13 +103,11 @@ class KpiDashboardItem(models.Model): name = fields.Char(required=True) kpi_id = fields.Many2one("kpi.kpi") - dashboard_id = fields.Many2one( - "kpi.dashboard", required=True, ondelete="cascade" - ) + dashboard_id = fields.Many2one("kpi.dashboard", required=True, ondelete="cascade") column = fields.Integer(required=True, default=1) row = fields.Integer(required=True, default=1) - end_row = fields.Integer(store=True, compute='_compute_end_row') - end_column = fields.Integer(store=True, compute='_compute_end_column') + end_row = fields.Integer(store=True, compute="_compute_end_row") + end_column = fields.Integer(store=True, compute="_compute_end_column") size_x = fields.Integer(required=True, default=1) size_y = fields.Integer(required=True, default=1) color = fields.Char() @@ -122,44 +117,43 @@ class KpiDashboardItem(models.Model): modify_color = fields.Boolean() modify_color_expression = fields.Char() - @api.depends('row', 'size_y') + @api.depends("row", "size_y") def _compute_end_row(self): for r in self: r.end_row = r.row + r.size_y - 1 - @api.depends('column', 'size_x') + @api.depends("column", "size_x") def _compute_end_column(self): for r in self: r.end_column = r.column + r.size_x - 1 - @api.constrains('size_y') + @api.constrains("size_y") def _check_size_y(self): for rec in self: if rec.size_y > 10: - raise ValidationError(_( - 'Size Y of the widget cannot be bigger than 10')) + raise ValidationError( + _("Size Y of the widget cannot be bigger than 10") + ) def _check_size_domain(self): return [ - ('dashboard_id', '=', self.dashboard_id.id), - ('id', '!=', self.id), - ('row', '<=', self.end_row), - ('end_row', '>=', self.row), - ('column', '<=', self.end_column), - ('end_column', '>=', self.column), + ("dashboard_id", "=", self.dashboard_id.id), + ("id", "!=", self.id), + ("row", "<=", self.end_row), + ("end_row", ">=", self.row), + ("column", "<=", self.end_column), + ("end_column", ">=", self.column), ] - @api.constrains('end_row', 'end_column', 'row', 'column') + @api.constrains("end_row", "end_column", "row", "column") def _check_size(self): for r in self: if self.search(r._check_size_domain(), limit=1): - raise ValidationError(_( - 'Widgets cannot be crossed by other widgets' - )) + raise ValidationError(_("Widgets cannot be crossed by other widgets")) if r.end_column > r.dashboard_id.number_of_columns: - raise ValidationError(_( - 'Widget %s is bigger than expected' - ) % r.display_name) + raise ValidationError( + _("Widget %s is bigger than expected") % r.display_name + ) @api.onchange("kpi_id") def _onchange_kpi(self): @@ -181,9 +175,9 @@ class KpiDashboardItem(models.Model): "modify_color": self.modify_color, } if self.modify_context: - vals['modify_context_expression'] = self.modify_context_expression + vals["modify_context_expression"] = self.modify_context_expression if self.modify_color: - vals['modify_color_expression'] = self.modify_color_expression + vals["modify_color_expression"] = self.modify_color_expression if self.kpi_id: vals.update( { @@ -195,15 +189,19 @@ class KpiDashboardItem(models.Model): } ) if self.kpi_id.compute_on_fly: - vals.update({ - "value": self.kpi_id._compute_value(), - "value_last_update": fields.Datetime.now(), - }) + vals.update( + { + "value": self.kpi_id._compute_value(), + "value_last_update": fields.Datetime.now(), + } + ) else: - vals.update({ - "value": self.kpi_id.value, - "value_last_update": self.kpi_id.value_last_update, - }) + vals.update( + { + "value": self.kpi_id.value, + "value_last_update": self.kpi_id.value_last_update, + } + ) if self.kpi_id.action_ids: vals["actions"] = self.kpi_id.action_ids.read_dashboard() else: @@ -219,12 +217,13 @@ class KpiDashboardItem(models.Model): def technical_config(self): self.ensure_one() return { - 'name': self.display_name, - 'res_model': self._name, - 'res_id': self.id, - 'type': 'ir.actions.act_window', - 'view_mode': 'form', - 'target': 'new', - 'view_id': self.env.ref( - 'kpi_dashboard.kpi_dashboard_item_config_form_view').id, + "name": self.display_name, + "res_model": self._name, + "res_id": self.id, + "type": "ir.actions.act_window", + "view_mode": "form", + "target": "new", + "view_id": self.env.ref( + "kpi_dashboard.kpi_dashboard_item_config_form_view" + ).id, } diff --git a/kpi_dashboard/models/kpi_kpi.py b/kpi_dashboard/models/kpi_kpi.py index a16d613d..11cb5fd9 100644 --- a/kpi_dashboard/models/kpi_kpi.py +++ b/kpi_dashboard/models/kpi_kpi.py @@ -1,17 +1,20 @@ # Copyright 2020 Creu Blanca # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ -from odoo.exceptions import ValidationError import ast -from odoo.tools.safe_eval import safe_eval -from odoo.addons.base.models.ir_cron import _intervalTypes -from odoo.tools.float_utils import float_compare -import re -import json import datetime +import json +import re + from dateutil import relativedelta +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools.float_utils import float_compare +from odoo.tools.safe_eval import safe_eval + +from odoo.addons.base.models.ir_cron import _intervalTypes + class KpiKpi(models.Model): _name = "kpi.kpi" @@ -30,8 +33,13 @@ class KpiKpi(models.Model): args = fields.Char() kwargs = fields.Char() widget = fields.Selection( - [('integer', 'Integer'), ("number", "Number"), ("meter", "Meter"), - ('counter', 'Counter'), ("graph", "Graph")], + [ + ("integer", "Integer"), + ("number", "Number"), + ("meter", "Meter"), + ("counter", "Counter"), + ("graph", "Graph"), + ], required=True, default="number", ) @@ -40,22 +48,21 @@ class KpiKpi(models.Model): suffix = fields.Char() action_ids = fields.One2many( "kpi.kpi.action", - inverse_name='kpi_id', - help="Actions that can be opened from the KPI" + inverse_name="kpi_id", + help="Actions that can be opened from the KPI", ) code = fields.Text("Code") store_history = fields.Boolean() store_history_interval = fields.Selection( - selection=lambda self: - self.env['ir.cron']._fields['interval_type'].selection, + selection=lambda self: self.env["ir.cron"]._fields["interval_type"].selection, ) store_history_interval_number = fields.Integer() compute_on_fly = fields.Boolean() history_ids = fields.One2many("kpi.kpi.history", inverse_name="kpi_id") - computed_value = fields.Serialized(compute='_compute_computed_value') - computed_date = fields.Datetime(compute='_compute_computed_value') + computed_value = fields.Serialized(compute="_compute_computed_value") + computed_date = fields.Datetime(compute="_compute_computed_value") - @api.depends('value', 'value_last_update', 'compute_on_fly') + @api.depends("value", "value_last_update", "compute_on_fly") def _compute_computed_value(self): for record in self: if record.compute_on_fly: @@ -95,18 +102,19 @@ class KpiKpi(models.Model): value = self._compute_value() self.write({"value": value}) if self.store_history: - last = self.env['kpi.kpi.history'].search([ - ('kpi_id', '=', self.id) - ], limit=1) + last = self.env["kpi.kpi.history"].search( + [("kpi_id", "=", self.id)], limit=1 + ) if ( - not last or - not self.store_history_interval or - last.create_date + _intervalTypes[self.store_history_interval]( - self.store_history_interval_number) < fields.Datetime.now() - ): - self.env["kpi.kpi.history"].create( - self._generate_history_vals(value) + not last + or not self.store_history_interval + or last.create_date + + _intervalTypes[self.store_history_interval]( + self.store_history_interval_number ) + < fields.Datetime.now() + ): + self.env["kpi.kpi.history"].create(self._generate_history_vals(value)) notifications = [] for dashboard_item in self.dashboard_item_ids: channel = "kpi_dashboard_%s" % dashboard_item.dashboard_id.id @@ -152,9 +160,9 @@ class KpiKpi(models.Model): if len(message) > 0: message += _(" or ") message += forbidden[-1] - raise ValidationError(_( - "The code cannot contain the following terms: %s." - ) % message) + raise ValidationError( + _("The code cannot contain the following terms: %s.") % message + ) results = self._get_code_input_dict() savepoint = "kpi_formula_%s" % self.id self.env.cr.execute("savepoint %s" % savepoint) @@ -164,30 +172,34 @@ class KpiKpi(models.Model): def show_value(self): self.ensure_one() - action = self.env.ref('kpi_dashboard.kpi_kpi_act_window') + action = self.env.ref("kpi_dashboard.kpi_kpi_act_window") result = action.read()[0] - result.update({ - 'res_id': self.id, - 'target': 'new', - 'view_mode': 'form', - 'views': [(self.env.ref( - 'kpi_dashboard.kpi_kpi_widget_form_view' - ).id, 'form')], - }) + result.update( + { + "res_id": self.id, + "target": "new", + "view_mode": "form", + "views": [ + (self.env.ref("kpi_dashboard.kpi_kpi_widget_form_view").id, "form") + ], + } + ) return result class KpiKpiAction(models.Model): - _name = 'kpi.kpi.action' - _description = 'KPI action' + _name = "kpi.kpi.action" + _description = "KPI action" - kpi_id = fields.Many2one('kpi.kpi', required=True, ondelete='cascade') + kpi_id = fields.Many2one("kpi.kpi", required=True, ondelete="cascade") action = fields.Reference( - selection=[('ir.actions.report', 'ir.actions.report'), - ('ir.actions.act_window', 'ir.actions.act_window'), - ('ir.actions.act_url', 'ir.actions.act_url'), - ('ir.actions.server', 'ir.actions.server'), - ('ir.actions.client', 'ir.actions.client')], + selection=[ + ("ir.actions.report", "ir.actions.report"), + ("ir.actions.act_window", "ir.actions.act_window"), + ("ir.actions.act_url", "ir.actions.act_url"), + ("ir.actions.server", "ir.actions.server"), + ("ir.actions.client", "ir.actions.client"), + ], required=True, ) context = fields.Char() @@ -196,43 +208,45 @@ class KpiKpiAction(models.Model): result = {} for r in self: result[r.id] = { - 'id': r.action.id, - 'type': r.action._name, - 'name': r.action.name, - 'context': safe_eval(r.context or '{}') + "id": r.action.id, + "type": r.action._name, + "name": r.action.name, + "context": safe_eval(r.context or "{}"), } return result class KpiKpiHistory(models.Model): - _name = 'kpi.kpi.history' - _description = 'KPI history' - _order = 'create_date DESC' + _name = "kpi.kpi.history" + _description = "KPI history" + _order = "create_date DESC" kpi_id = fields.Many2one( - 'kpi.kpi', required=True, ondelete='cascade', readonly=True + "kpi.kpi", required=True, ondelete="cascade", readonly=True ) value = fields.Serialized(readonly=True) - raw_value = fields.Char(compute='_compute_raw_value') - name = fields.Char(related='kpi_id.name') + raw_value = fields.Char(compute="_compute_raw_value") + name = fields.Char(related="kpi_id.name") widget = fields.Selection( - selection=lambda self: - self.env['kpi.kpi']._fields['widget'].selection, - required=True) + selection=lambda self: self.env["kpi.kpi"]._fields["widget"].selection, + required=True, + ) - @api.depends('value') + @api.depends("value") def _compute_raw_value(self): for record in self: record.raw_value = json.dumps(record.value) def show_form(self): self.ensure_one() - action = self.env.ref('kpi_dashboard.kpi_kpi_history_act_window') + action = self.env.ref("kpi_dashboard.kpi_kpi_history_act_window") result = action.read()[0] - result.update({ - 'res_id': self.id, - 'target': 'new', - 'view_mode': 'form', - 'views': [(self.env.context.get('form_id'), 'form')], - }) + result.update( + { + "res_id": self.id, + "target": "new", + "view_mode": "form", + "views": [(self.env.context.get("form_id"), "form")], + } + ) return result diff --git a/kpi_dashboard/security/security.xml b/kpi_dashboard/security/security.xml index fb16b0f7..dd87e7c2 100755 --- a/kpi_dashboard/security/security.xml +++ b/kpi_dashboard/security/security.xml @@ -1,22 +1,24 @@ - + Manage KPI Dashboards - - + + KPI Dashboard: User - - ['|', ('group_ids', '=', False), ('group_ids', 'in', user.groups_id.ids)] - + + ['|', ('group_ids', '=', False), ('group_ids', 'in', user.groups_id.ids)] + KPI Dashboard: All - + [(1, '=', 1)] - + diff --git a/kpi_dashboard/static/src/js/dashboard_controller.js b/kpi_dashboard/static/src/js/dashboard_controller.js index 97db1765..7910f82c 100644 --- a/kpi_dashboard/static/src/js/dashboard_controller.js +++ b/kpi_dashboard/static/src/js/dashboard_controller.js @@ -1,150 +1,159 @@ -odoo.define('kpi_dashboard.DashboardController', function (require) { +odoo.define("kpi_dashboard.DashboardController", function(require) { "use strict"; - var BasicController = require('web.BasicController'); - var core = require('web.core'); + var BasicController = require("web.BasicController"); + var core = require("web.core"); var qweb = core.qweb; var _t = core._t; var DashboardController = BasicController.extend({ - init: function () { + init: function() { this._super.apply(this, arguments); this.dashboard_context = {}; - this.dashboard_color_data = [] + this.dashboard_color_data = []; }, custom_events: _.extend({}, BasicController.prototype.custom_events, { - addDashboard: '_addDashboard', - refresh_on_fly: '_refreshOnFly', - modify_context: '_modifyContext', - add_modify_color: '_addModifyColor', - refresh_colors: '_refreshColors', + addDashboard: "_addDashboard", + refresh_on_fly: "_refreshOnFly", + modify_context: "_modifyContext", + add_modify_color: "_addModifyColor", + refresh_colors: "_refreshColors", }), - _refreshOnFly: function (event) { + _refreshOnFly: function(event) { var self = this; this._rpc({ model: this.modelName, - method: 'read_dashboard_on_fly', + method: "read_dashboard_on_fly", args: [[this.renderer.state.res_id]], context: this._getContext(), - }).then(function (data) { - _.each(data, function (item) { + }).then(function(data) { + _.each(data, function(item) { // We will follow the same logic used on Bus Notifications - self.renderer._onNotification([[ - "kpi_dashboard_" + self.renderer.state.res_id, - item - ]]) + self.renderer._onNotification([ + ["kpi_dashboard_" + self.renderer.state.res_id, item], + ]); }); }); }, - renderPager: function ($node, options) { + renderPager: function($node, options) { options = _.extend({}, options, { validate: this.canBeDiscarded.bind(this), }); this._super($node, options); }, - _pushState: function (state) { + _pushState: function(state) { state = state || {}; var env = this.model.get(this.handle, {env: true}); state.id = env.currentId; this._super(state); }, - _addDashboard: function () { + _addDashboard: function() { var self = this; var action = self.initialState.specialData.action_id; var name = self.initialState.specialData.name; - if (! action) { + if (!action) { self.do_warn(_t("First you must create the Menu")); } - return self._rpc({ - route: '/board/add_to_dashboard', - params: { - action_id: action, - context_to_save: {'res_id': self.initialState.res_id}, - domain: [('id', '=', self.initialState.res_id)], - view_mode: 'dashboard', - name: name, - }, - }) - .then(function (r) { - if (r) { - self.do_notify( - _.str.sprintf(_t("'%s' added to dashboard"), name), - _t('Please refresh your browser for the changes to take effect.') - ); - } else { - self.do_warn(_t("Could not add KPI dashboard to dashboard")); - } - }); + return self + ._rpc({ + route: "/board/add_to_dashboard", + params: { + action_id: action, + context_to_save: {res_id: self.initialState.res_id}, + domain: [("id", "=", self.initialState.res_id)], + view_mode: "dashboard", + name: name, + }, + }) + .then(function(r) { + if (r) { + self.do_notify( + _.str.sprintf(_t("'%s' added to dashboard"), name), + _t( + "Please refresh your browser for the changes to take effect." + ) + ); + } else { + self.do_warn(_t("Could not add KPI dashboard to dashboard")); + } + }); }, - _updateButtons: function () { + _updateButtons: function() { // HOOK Function this.$buttons.on( - 'click', '.o_dashboard_button_add', - this._addDashboard.bind(this)); + "click", + ".o_dashboard_button_add", + this._addDashboard.bind(this) + ); }, - renderButtons: function ($node) { - if (! $node) { + renderButtons: function($node) { + if (!$node) { return; } - this.$buttons = $('
'); - this.$buttons.append(qweb.render( - "kpi_dashboard.buttons", {widget: this})); + this.$buttons = $("
"); + this.$buttons.append(qweb.render("kpi_dashboard.buttons", {widget: this})); this._updateButtons(); this.$buttons.appendTo($node); }, - _getContext: function () { + _getContext: function() { return _.extend( {}, this.model.get(this.handle, {raw: true}).getContext(), {bin_size: true}, - this.dashboard_context, - ) + this.dashboard_context + ); }, - _modifyContext: function (event) { + _modifyContext: function(event) { var ctx = this._getContext(); this.dashboard_context = _.extend( this.dashboard_context, - py.eval(event.data.context, {context: _.extend( - ctx, - {__getattr__: function() {return false}} - // We need to add this in order to allow to use undefined - // context items - )}), + py.eval(event.data.context, { + context: _.extend( + ctx, + { + __getattr__: function() { + return false; + }, + } + // We need to add this in order to allow to use undefined + // context items + ), + }) ); this._refreshOnFly(event); this._refreshColors(); }, - _addModifyColor: function (event) { + _addModifyColor: function(event) { this.dashboard_color_data.push([ event.data.element_id, event.data.expression, ]); }, - _refreshColors: function () { + _refreshColors: function() { var self = this; var ctx = this._getContext(); - _.each(this.dashboard_color_data, function (data) { + _.each(this.dashboard_color_data, function(data) { var color = py.eval(data[1], { context: _.extend(ctx, { - __getattr__: function() {return false}, - + __getattr__: function() { + return false; + }, }), check_if: function(args) { if (args[0].toJSON()) { return args[1]; } return args[2]; - } + }, }); - var $element = self.renderer.$el.find('#' + data[0]); - $element.css('background-color', color); + var $element = self.renderer.$el.find("#" + data[0]); + $element.css("background-color", color); }); }, }); return DashboardController; - }); diff --git a/kpi_dashboard/static/src/js/dashboard_model.js b/kpi_dashboard/static/src/js/dashboard_model.js index ddf7425e..93f0eb5c 100644 --- a/kpi_dashboard/static/src/js/dashboard_model.js +++ b/kpi_dashboard/static/src/js/dashboard_model.js @@ -1,23 +1,21 @@ -odoo.define('kpi_dashboard.DashboardModel', function (require) { +odoo.define("kpi_dashboard.DashboardModel", function(require) { "use strict"; - var BasicModel = require('web.BasicModel'); + var BasicModel = require("web.BasicModel"); var DashboardModel = BasicModel.extend({ - _fetchRecord: function (record, options) { + _fetchRecord: function(record, options) { return this._rpc({ model: record.model, - method: 'read_dashboard', + method: "read_dashboard", args: [[record.res_id]], context: _.extend({}, record.getContext(), {bin_size: true}), - }) - .then(function (result) { + }).then(function(result) { record.specialData = result; - return result - }) - } + return result; + }); + }, }); return DashboardModel; - }); diff --git a/kpi_dashboard/static/src/js/dashboard_renderer.js b/kpi_dashboard/static/src/js/dashboard_renderer.js index 6bc38c49..0caa85fc 100644 --- a/kpi_dashboard/static/src/js/dashboard_renderer.js +++ b/kpi_dashboard/static/src/js/dashboard_renderer.js @@ -1,99 +1,98 @@ -odoo.define('kpi_dashboard.DashboardRenderer', function (require) { +odoo.define("kpi_dashboard.DashboardRenderer", function(require) { "use strict"; - var BasicRenderer = require('web.BasicRenderer'); - var core = require('web.core'); - var registry = require('kpi_dashboard.widget_registry'); - var BusService = require('bus.BusService'); + var BasicRenderer = require("web.BasicRenderer"); + var core = require("web.core"); + var registry = require("kpi_dashboard.widget_registry"); + var BusService = require("bus.BusService"); var qweb = core.qweb; - var DashboardRenderer= BasicRenderer.extend({ + var DashboardRenderer = BasicRenderer.extend({ className: "o_dashboard_view", - _getDashboardWidget: function (kpi) { - var Widget = registry.getAny([ - kpi.widget, 'abstract', - ]); + _getDashboardWidget: function(kpi) { + var Widget = registry.getAny([kpi.widget, "abstract"]); var widget = new Widget(this, kpi); return widget; }, - _onClickModifyContext: function (modify_context_expression, event) { - this.trigger_up('modify_context', { + _onClickModifyContext: function(modify_context_expression, event) { + this.trigger_up("modify_context", { context: modify_context_expression, event: event, - }) + }); }, - _renderView: function () { - this.$el.html($(qweb.render('dashboard_kpi.dashboard'))); - this.$el.css( - 'background-color', this.state.specialData.background_color); - this.$el.find('.gridster') - .css('width', this.state.specialData.width); - this.$grid = this.$el.find('.gridster ul'); + _renderView: function() { + this.$el.html($(qweb.render("dashboard_kpi.dashboard"))); + this.$el.css("background-color", this.state.specialData.background_color); + this.$el.find(".gridster").css("width", this.state.specialData.width); + this.$grid = this.$el.find(".gridster ul"); var self = this; this.kpi_widget = {}; - _.each(this.state.specialData.item_ids, function (kpi) { - var element = $(qweb.render( - 'kpi_dashboard.kpi', {widget: kpi})); - element.css('background-color', kpi.color); - element.css('color', kpi.font_color); - element.attr('id', _.uniqueId('kpi_')); + _.each(this.state.specialData.item_ids, function(kpi) { + var element = $(qweb.render("kpi_dashboard.kpi", {widget: kpi})); + element.css("background-color", kpi.color); + element.css("color", kpi.font_color); + element.attr("id", _.uniqueId("kpi_")); self.$grid.append(element); if (kpi.modify_color) { self.trigger_up("add_modify_color", { element_id: element.attr("id"), expression: kpi.modify_color_expression, - }) + }); } if (kpi.modify_context) { - element.on("click", self._onClickModifyContext.bind( - self, kpi.modify_context_expression)); - element.css('cursor', 'pointer'); + element.on( + "click", + self._onClickModifyContext.bind( + self, + kpi.modify_context_expression + ) + ); + element.css("cursor", "pointer"); // We want to set it show as clickable } self.kpi_widget[kpi.id] = self._getDashboardWidget(kpi); self.kpi_widget[kpi.id].appendTo(element); }); - this.$grid.gridster({ - widget_margins: [ - this.state.specialData.margin_x, - this.state.specialData.margin_y, - ], - widget_base_dimensions: [ - this.state.specialData.widget_dimension_x, - this.state.specialData.widget_dimension_y, - ], - cols: this.state.specialData.max_cols, - }).data('gridster').disable(); - this.channel = 'kpi_dashboard_' + this.state.res_id; - this.call( - 'bus_service', 'addChannel', this.channel); - this.call('bus_service', 'startPolling'); - this.call( - 'bus_service', 'onNotification', - this, this._onNotification - ); + this.$grid + .gridster({ + widget_margins: [ + this.state.specialData.margin_x, + this.state.specialData.margin_y, + ], + widget_base_dimensions: [ + this.state.specialData.widget_dimension_x, + this.state.specialData.widget_dimension_y, + ], + cols: this.state.specialData.max_cols, + }) + .data("gridster") + .disable(); + this.channel = "kpi_dashboard_" + this.state.res_id; + this.call("bus_service", "addChannel", this.channel); + this.call("bus_service", "startPolling"); + this.call("bus_service", "onNotification", this, this._onNotification); if (this.state.specialData.compute_on_fly_refresh > 0) { // Setting the refresh interval - this.on_fly_interval = setInterval(function () { - self.trigger_up('refresh_on_fly'); - }, this.state.specialData.compute_on_fly_refresh *1000); - }; - this.trigger_up('refresh_colors'); - this.trigger_up('refresh_on_fly'); + this.on_fly_interval = setInterval(function() { + self.trigger_up("refresh_on_fly"); + }, this.state.specialData.compute_on_fly_refresh * 1000); + } + this.trigger_up("refresh_colors"); + this.trigger_up("refresh_on_fly"); // We need to refreshs data in order compute with the current // context return $.when(); }, - on_detach_callback: function () { + on_detach_callback: function() { // We want to clear the refresh interval once we exit the view if (this.on_fly_interval) { - clearInterval(this.on_fly_interval) + clearInterval(this.on_fly_interval); } this._super.apply(this, arguments); }, - _onNotification: function (notifications) { + _onNotification: function(notifications) { var self = this; - _.each(notifications, function (notification) { + _.each(notifications, function(notification) { var channel = notification[0]; var message = notification[1]; if (channel === self.channel && message) { diff --git a/kpi_dashboard/static/src/js/dashboard_view.js b/kpi_dashboard/static/src/js/dashboard_view.js index b31df5cb..e83dc991 100644 --- a/kpi_dashboard/static/src/js/dashboard_view.js +++ b/kpi_dashboard/static/src/js/dashboard_view.js @@ -1,26 +1,22 @@ -odoo.define('kpi_dashboard.DashboardView', function (require) { +odoo.define("kpi_dashboard.DashboardView", function(require) { "use strict"; - var BasicView = require('web.BasicView'); - var DashboardController = require('kpi_dashboard.DashboardController'); - var DashboardModel = require('kpi_dashboard.DashboardModel'); - var DashboardRenderer = require('kpi_dashboard.DashboardRenderer'); - var view_registry = require('web.view_registry'); - var core = require('web.core'); + var BasicView = require("web.BasicView"); + var DashboardController = require("kpi_dashboard.DashboardController"); + var DashboardModel = require("kpi_dashboard.DashboardModel"); + var DashboardRenderer = require("kpi_dashboard.DashboardRenderer"); + var view_registry = require("web.view_registry"); + var core = require("web.core"); var _lt = core._lt; var DashboardView = BasicView.extend({ - jsLibs: [ - '/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.js', - ], - cssLibs: [ - '/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.css', - ], + jsLibs: ["/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.js"], + cssLibs: ["/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.css"], accesskey: "d", display_name: _lt("Dashboard"), - icon: 'fa-tachometer', - viewType: 'dashboard', + icon: "fa-tachometer", + viewType: "dashboard", config: _.extend({}, BasicView.prototype.config, { Controller: DashboardController, Renderer: DashboardRenderer, @@ -28,17 +24,17 @@ odoo.define('kpi_dashboard.DashboardView', function (require) { }), multi_record: false, searchable: false, - init: function () { + init: function() { this._super.apply(this, arguments); - this.controllerParams.mode = 'readonly'; - this.loadParams.type = 'record'; - if (! this.loadParams.res_id && this.loadParams.context.res_id) { + this.controllerParams.mode = "readonly"; + this.loadParams.type = "record"; + if (!this.loadParams.res_id && this.loadParams.context.res_id) { this.loadParams.res_id = this.loadParams.context.res_id; } }, }); - view_registry.add('dashboard', DashboardView); + view_registry.add("dashboard", DashboardView); return DashboardView; }); diff --git a/kpi_dashboard/static/src/js/field_widget.js b/kpi_dashboard/static/src/js/field_widget.js index 2a25003e..3c9a6140 100644 --- a/kpi_dashboard/static/src/js/field_widget.js +++ b/kpi_dashboard/static/src/js/field_widget.js @@ -1,28 +1,24 @@ -odoo.define('kpi_dashboard.KpiFieldWidget', function(require) { +odoo.define("kpi_dashboard.KpiFieldWidget", function(require) { "use strict"; - var basic_fields = require('web.basic_fields'); - var field_registry = require('web.field_registry'); - var core = require('web.core'); + var basic_fields = require("web.basic_fields"); + var field_registry = require("web.field_registry"); + var core = require("web.core"); var qweb = core.qweb; - var registry = require('kpi_dashboard.widget_registry'); + var registry = require("kpi_dashboard.widget_registry"); var KpiFieldWidget = basic_fields.FieldChar.extend({ - jsLibs: [ - '/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.js', - ], - cssLibs: [ - '/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.css', - ], - className: 'o_dashboard_view', - _renderReadonly: function () { - this.$el.html($(qweb.render('dashboard_kpi.dashboard'))); + jsLibs: ["/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.js"], + cssLibs: ["/kpi_dashboard/static/lib/gridster/jquery.dsmorse-gridster.min.css"], + className: "o_dashboard_view", + _renderReadonly: function() { + this.$el.html($(qweb.render("dashboard_kpi.dashboard"))); var marginx = 0; var marginy = 0; var widgetx = 400; var widgety = 400; - this.$el.find('.gridster').css('width', widgety); - this.$grid = this.$el.find('.gridster ul'); + this.$el.find(".gridster").css("width", widgety); + this.$grid = this.$el.find(".gridster ul"); var widgetVals = { value: this.value, col: 1, @@ -30,10 +26,11 @@ odoo.define('kpi_dashboard.KpiFieldWidget', function(require) { sizex: 1, sizey: 1, name: this.recordData[this.nodeOptions.name], - value_last_update: this.recordData[this.nodeOptions.date] - } + value_last_update: this.recordData[this.nodeOptions.date], + }; var Widget = registry.getAny([ - this.recordData[this.nodeOptions.widget], 'abstract', + this.recordData[this.nodeOptions.widget], + "abstract", ]); this.state = { specialData: { @@ -41,28 +38,24 @@ odoo.define('kpi_dashboard.KpiFieldWidget', function(require) { margin_y: marginy, widget_dimension_x: widgetx, widget_dimension_y: widgety, - } - } + }, + }; var widget = new Widget(this, widgetVals); - var element = $(qweb.render( - 'kpi_dashboard.kpi', {widget: widgetVals})); - element.css('background-color', 'white'); - element.css('color', 'black'); + var element = $(qweb.render("kpi_dashboard.kpi", {widget: widgetVals})); + element.css("background-color", "white"); + element.css("color", "black"); this.$grid.append(element); - widget.appendTo(element) - this.$grid.gridster({ - widget_margins: [ - marginx, - marginy, - ], - widget_base_dimensions: [ - widgetx, - widgety, - ], - cols: 1, - }).data('gridster').disable(); + widget.appendTo(element); + this.$grid + .gridster({ + widget_margins: [marginx, marginy], + widget_base_dimensions: [widgetx, widgety], + cols: 1, + }) + .data("gridster") + .disable(); }, }); - field_registry.add('kpi', KpiFieldWidget); + field_registry.add("kpi", KpiFieldWidget); return KpiFieldWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/abstract_widget.js b/kpi_dashboard/static/src/js/widget/abstract_widget.js index 470054f3..0d1ffb4f 100644 --- a/kpi_dashboard/static/src/js/widget/abstract_widget.js +++ b/kpi_dashboard/static/src/js/widget/abstract_widget.js @@ -1,20 +1,20 @@ -odoo.define('kpi_dashboard.AbstractWidget', function (require) { +odoo.define("kpi_dashboard.AbstractWidget", function(require) { "use strict"; - var Widget = require('web.Widget'); - var field_utils = require('web.field_utils'); - var time = require('web.time'); - var ajax = require('web.ajax'); - var registry = require('kpi_dashboard.widget_registry'); + var Widget = require("web.Widget"); + var field_utils = require("web.field_utils"); + var time = require("web.time"); + var ajax = require("web.ajax"); + var registry = require("kpi_dashboard.widget_registry"); var AbstractWidget = Widget.extend({ - template: 'kpi_dashboard.base_widget', // Template used by the widget + template: "kpi_dashboard.base_widget", // Template used by the widget cssLibs: [], // Specific css of the widget jsLibs: [], // Specific Javascript libraries of the widget events: { - 'click .o_kpi_dashboard_toggle_button': '_onClickToggleButton', - 'click .direct_action': '_onClickDirectAction', + "click .o_kpi_dashboard_toggle_button": "_onClickToggleButton", + "click .direct_action": "_onClickDirectAction", }, - init: function (parent, kpi_values) { + init: function(parent, kpi_values) { this._super(parent); this.col = kpi_values.col; this.row = kpi_values.row; @@ -29,66 +29,70 @@ odoo.define('kpi_dashboard.AbstractWidget', function (require) { this.prefix = kpi_values.prefix; this.suffix = kpi_values.suffix; this.actions = kpi_values.actions; - this.widget_size_x = this.widget_dimension_x * this.sizex + - (this.sizex - 1) * this.margin_x; - this.widget_size_y = this.widget_dimension_y * this.sizey + - (this.sizey - 1) * this.margin_y; + this.widget_size_x = + this.widget_dimension_x * this.sizex + (this.sizex - 1) * this.margin_x; + this.widget_size_y = + this.widget_dimension_y * this.sizey + (this.sizey - 1) * this.margin_y; }, - willStart: function () { + willStart: function() { // We need to load the libraries before the start return $.when(ajax.loadLibs(this), this._super.apply(this, arguments)); }, - start: function () { + start: function() { var self = this; - return this._super.apply(this, arguments).then(function () { + return this._super.apply(this, arguments).then(function() { self._fillWidget(self.values); }); }, - _onClickToggleButton: function (event) { + _onClickToggleButton: function(event) { event.preventDefault(); - this.$el.toggleClass('o_dropdown_open'); + this.$el.toggleClass("o_dropdown_open"); }, - _fillWidget: function (values) { + _fillWidget: function(values) { // This function fills the widget values - if (this.$el === undefined) - return; + if (this.$el === undefined) return; this.fillWidget(values); var item = this.$el.find('[data-bind="value_last_update_display"]'); - if (item && ! values.compute_on_fly && values.value_last_update !== undefined) { + if ( + item && + !values.compute_on_fly && + values.value_last_update !== undefined + ) { var value = field_utils.parse.datetime(values.value_last_update); - item.text(value.clone().add( - this.getSession().getTZOffset(value), 'minutes').format( - time.getLangDatetimeFormat() - )); + item.text( + value + .clone() + .add(this.getSession().getTZOffset(value), "minutes") + .format(time.getLangDatetimeFormat()) + ); } - var $manage = this.$el.find('.o_kpi_dashboard_manage'); + var $manage = this.$el.find(".o_kpi_dashboard_manage"); if ($manage && this.showManagePanel(values)) - $manage.toggleClass('hidden', false); + $manage.toggleClass("hidden", false); }, - showManagePanel: function (values) { + showManagePanel: function(values) { // Hook for extensions - return (values.actions !== undefined); + return values.actions !== undefined; }, - fillWidget: function (values) { + fillWidget: function(values) { // Specific function that will be changed by specific widget var value = values.value; var self = this; - _.each(value, function (val, key) { - var item = self.$el.find('[data-bind=' + key + ']') - if (item) - item.text(val); - }) + _.each(value, function(val, key) { + var item = self.$el.find("[data-bind=" + key + "]"); + if (item) item.text(val); + }); }, _onClickDirectAction: function(event) { event.preventDefault(); - var $data = $(event.currentTarget).closest('a'); - var action = this.actions[$($data).data('id')]; + var $data = $(event.currentTarget).closest("a"); + var action = this.actions[$($data).data("id")]; return this.do_action(action.id, { - additional_context: action.context + additional_context: action.context, }); - } + }, }); - registry.add('abstract', AbstractWidget); + registry.add("abstract", AbstractWidget); return AbstractWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/counter_widget.js b/kpi_dashboard/static/src/js/widget/counter_widget.js index 6005298f..019afd67 100644 --- a/kpi_dashboard/static/src/js/widget/counter_widget.js +++ b/kpi_dashboard/static/src/js/widget/counter_widget.js @@ -1,14 +1,14 @@ -odoo.define('kpi_dashboard.CounterWidget', function (require) { +odoo.define("kpi_dashboard.CounterWidget", function(require) { "use strict"; - var IntegerWidget = require('kpi_dashboard.IntegerWidget'); - var registry = require('kpi_dashboard.widget_registry'); - var field_utils = require('web.field_utils'); + var IntegerWidget = require("kpi_dashboard.IntegerWidget"); + var registry = require("kpi_dashboard.widget_registry"); + var field_utils = require("web.field_utils"); var CounterWidget = IntegerWidget.extend({ shortList: [], }); - registry.add('counter', CounterWidget); + registry.add("counter", CounterWidget); return CounterWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/graph_widget.js b/kpi_dashboard/static/src/js/widget/graph_widget.js index 94d60688..d3e49226 100644 --- a/kpi_dashboard/static/src/js/widget/graph_widget.js +++ b/kpi_dashboard/static/src/js/widget/graph_widget.js @@ -1,40 +1,39 @@ -odoo.define('kpi_dashboard.GraphWidget', function (require) { +odoo.define("kpi_dashboard.GraphWidget", function(require) { "use strict"; - var AbstractWidget = require('kpi_dashboard.AbstractWidget'); - var registry = require('kpi_dashboard.widget_registry'); - var core = require('web.core'); + var AbstractWidget = require("kpi_dashboard.AbstractWidget"); + var registry = require("kpi_dashboard.widget_registry"); + var core = require("web.core"); var qweb = core.qweb; - var GraphWidget = AbstractWidget.extend({ - template: 'kpi_dashboard.graph', + template: "kpi_dashboard.graph", jsLibs: [ - '/web/static/lib/nvd3/d3.v3.js', - '/web/static/lib/nvd3/nv.d3.js', - '/web/static/src/js/libs/nvd3.js', - ], - cssLibs: [ - '/web/static/lib/nvd3/nv.d3.css', + "/web/static/lib/nvd3/d3.v3.js", + "/web/static/lib/nvd3/nv.d3.js", + "/web/static/src/js/libs/nvd3.js", ], - start: function () { + cssLibs: ["/web/static/lib/nvd3/nv.d3.css"], + start: function() { this._onResize = this._onResize.bind(this); nv.utils.windowResize(this._onResize); return this._super.apply(this, arguments); }, - destroy: function () { - if ('nv' in window && nv.utils && nv.utils.offWindowResize) { - // if the widget is destroyed before the lazy loaded libs (nv) are + destroy: function() { + if ("nv" in window && nv.utils && nv.utils.offWindowResize) { + // If the widget is destroyed before the lazy loaded libs (nv) are // actually loaded (i.e. after the widget has actually started), // nv is undefined, but the handler isn't bound yet anyway nv.utils.offWindowResize(this._onResize); } this._super.apply(this, arguments); }, - _getChartOptions: function (values) { + _getChartOptions: function(values) { return { - x: function (d, u) { return u; }, - margin: {'left': 0, 'right': 0, 'top': 5, 'bottom': 0}, + x: function(d, u) { + return u; + }, + margin: {left: 0, right: 0, top: 5, bottom: 0}, showYAxis: false, showXAxis: false, showLegend: false, @@ -42,60 +41,58 @@ odoo.define('kpi_dashboard.GraphWidget', function (require) { width: this.widget_size_x - 20, }; }, - _chartConfiguration: function (values) { - + _chartConfiguration: function(values) { this.chart.forceY([0]); - this.chart.xAxis.tickFormat(function (d) { - var label = ''; - _.each(values.value.graphs, function (v) { + this.chart.xAxis.tickFormat(function(d) { + var label = ""; + _.each(values.value.graphs, function(v) { if (v.values[d] && v.values[d].x) { label = v.values[d].x; } }); return label; }); - this.chart.yAxis.tickFormat(d3.format(',.2f')); + this.chart.yAxis.tickFormat(d3.format(",.2f")); - this.chart.tooltip.contentGenerator(function (key) { - return qweb.render('GraphCustomTooltip', { - 'color': key.point.color, - 'key': key.series[0].title, - 'value': d3.format(',.2f')(key.point.y) + this.chart.tooltip.contentGenerator(function(key) { + return qweb.render("GraphCustomTooltip", { + color: key.point.color, + key: key.series[0].title, + value: d3.format(",.2f")(key.point.y), }); }); }, - _addGraph: function (values) { + _addGraph: function(values) { var data = values.value.graphs; - this.$svg.addClass('o_graph_linechart'); + this.$svg.addClass("o_graph_linechart"); this.chart = nv.models.lineChart(); - this.chart.options( - this._getChartOptions(values) - ); + this.chart.options(this._getChartOptions(values)); this._chartConfiguration(values); - d3.select(this.$('svg')[0]) + d3.select(this.$("svg")[0]) .datum(data) - .transition().duration(600) + .transition() + .duration(600) .call(this.chart); - this.$('svg').css('height', this.widget_size_y - 90); + this.$("svg").css("height", this.widget_size_y - 90); this._customizeChart(); }, - fillWidget: function (values) { + fillWidget: function(values) { var self = this; var element = this.$el.find('[data-bind="value"]'); element.empty(); - element.css('padding-left', 10).css('padding-right', 10); + element.css("padding-left", 10).css("padding-right", 10); this.chart = null; - nv.addGraph(function () { - self.$svg = self.$el.find( - '[data-bind="value"]' - ).append(''); + nv.addGraph(function() { + self.$svg = self.$el + .find('[data-bind="value"]') + .append(""); self._addGraph(values); }); }, - _customizeChart: function () { + _customizeChart: function() { // Hook function }, - _onResize: function () { + _onResize: function() { if (this.chart) { this.chart.update(); this._customizeChart(); @@ -103,6 +100,6 @@ odoo.define('kpi_dashboard.GraphWidget', function (require) { }, }); - registry.add('graph', GraphWidget); + registry.add("graph", GraphWidget); return GraphWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/integer_widget.js b/kpi_dashboard/static/src/js/widget/integer_widget.js index 7b9354d6..615ac238 100644 --- a/kpi_dashboard/static/src/js/widget/integer_widget.js +++ b/kpi_dashboard/static/src/js/widget/integer_widget.js @@ -1,36 +1,38 @@ -odoo.define('kpi_dashboard.IntegerWidget', function (require) { +odoo.define("kpi_dashboard.IntegerWidget", function(require) { "use strict"; - var AbstractWidget = require('kpi_dashboard.AbstractWidget'); - var registry = require('kpi_dashboard.widget_registry'); - var field_utils = require('web.field_utils'); - + var AbstractWidget = require("kpi_dashboard.AbstractWidget"); + var registry = require("kpi_dashboard.widget_registry"); + var field_utils = require("web.field_utils"); var IntegerWidget = AbstractWidget.extend({ - template: 'kpi_dashboard.number', + template: "kpi_dashboard.number", digits: [3, 0], shortList: [ - [1000000000000, 'T', [3, 1]], - [1000000000, 'G', [3, 1]], - [1000000, 'M', [3, 1]], - [1000, 'K', [3, 1]] + [1000000000000, "T", [3, 1]], + [1000000000, "G", [3, 1]], + [1000000, "M", [3, 1]], + [1000, "K", [3, 1]], ], - shortNumber: function (num) { - var suffix = ''; + shortNumber: function(num) { + var suffix = ""; var shortened = false; var digits = this.digits; - _.each(this.shortList, function (shortItem) { + _.each(this.shortList, function(shortItem) { if (!shortened && Math.abs(num) >= shortItem[0]) { shortened = true; suffix = shortItem[1]; - num = num / shortItem[0]; + num /= shortItem[0]; digits = shortItem[2]; } }); - return field_utils.format.float(num, false, { - digits: digits}) + suffix; + return ( + field_utils.format.float(num, false, { + digits: digits, + }) + suffix + ); }, - fillWidget: function (values) { + fillWidget: function(values) { var widget = this.$el; var value = values.value.value; if (value === undefined) { @@ -42,30 +44,31 @@ odoo.define('kpi_dashboard.IntegerWidget', function (require) { } var previous = values.value.previous; - var $change_rate = widget.find('.change-rate'); + var $change_rate = widget.find(".change-rate"); if (previous === undefined) { - $change_rate.toggleClass('active', false); + $change_rate.toggleClass("active", false); } else { var difference = 0; if (previous !== 0) { - difference = field_utils.format.integer( - (100 * value / previous) - 100) + '%'; + difference = + field_utils.format.integer((100 * value) / previous - 100) + + "%"; } - $change_rate.toggleClass('active', true); + $change_rate.toggleClass("active", true); var $difference = widget.find('[data-bind="difference"]'); $difference.text(difference); var $arrow = widget.find('[data-bind="arrow"]'); if (value < previous) { - $arrow.toggleClass('fa-arrow-up', false); - $arrow.toggleClass('fa-arrow-down', true); + $arrow.toggleClass("fa-arrow-up", false); + $arrow.toggleClass("fa-arrow-down", true); } else { - $arrow.toggleClass('fa-arrow-up', true); - $arrow.toggleClass('fa-arrow-down', false); + $arrow.toggleClass("fa-arrow-up", true); + $arrow.toggleClass("fa-arrow-down", false); } } }, }); - registry.add('integer', IntegerWidget); + registry.add("integer", IntegerWidget); return IntegerWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/meter_widget.js b/kpi_dashboard/static/src/js/widget/meter_widget.js index 3d342a2a..9c1353d5 100644 --- a/kpi_dashboard/static/src/js/widget/meter_widget.js +++ b/kpi_dashboard/static/src/js/widget/meter_widget.js @@ -1,39 +1,34 @@ -odoo.define('kpi_dashboard.MeterWidget', function (require) { +odoo.define("kpi_dashboard.MeterWidget", function(require) { "use strict"; - var AbstractWidget = require('kpi_dashboard.AbstractWidget'); - var registry = require('kpi_dashboard.widget_registry'); - + var AbstractWidget = require("kpi_dashboard.AbstractWidget"); + var registry = require("kpi_dashboard.widget_registry"); var MeterWidget = AbstractWidget.extend({ - template: 'kpi_dashboard.meter', - jsLibs: [ - '/kpi_dashboard/static/lib/gauge/GaugeMeter.js', - ], - fillWidget: function (values) { + template: "kpi_dashboard.meter", + jsLibs: ["/kpi_dashboard/static/lib/gauge/GaugeMeter.js"], + fillWidget: function(values) { var input = this.$el.find('[data-bind="value"]'); var options = this._getMeterOptions(values); - var margin = (this.widget_dimension_x - options.size)/2; + var margin = (this.widget_dimension_x - options.size) / 2; input.gaugeMeter(options); - input.parent().css('padding-left', margin); + input.parent().css("padding-left", margin); }, - _getMeterOptions: function (values) { - var size = Math.min( - this.widget_size_x, - this.widget_size_y - 40) - 10; + _getMeterOptions: function(values) { + var size = Math.min(this.widget_size_x, this.widget_size_y - 40) - 10; return { percent: values.value.value, - style: 'Arch', + style: "Arch", width: 10, size: size, - prepend: values.prefix !== undefined ? values.prefix : '', - append: values.suffix !== undefined ? values.suffix : '', + prepend: values.prefix !== undefined ? values.prefix : "", + append: values.suffix !== undefined ? values.suffix : "", color: values.font_color, animate_text_colors: true, }; }, }); - registry.add('meter', MeterWidget); + registry.add("meter", MeterWidget); return MeterWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/number_widget.js b/kpi_dashboard/static/src/js/widget/number_widget.js index 569f8cf2..92b9e048 100644 --- a/kpi_dashboard/static/src/js/widget/number_widget.js +++ b/kpi_dashboard/static/src/js/widget/number_widget.js @@ -1,21 +1,22 @@ -odoo.define('kpi_dashboard.NumberWidget', function (require) { +odoo.define("kpi_dashboard.NumberWidget", function(require) { "use strict"; - var IntegerWidget = require('kpi_dashboard.IntegerWidget'); - var registry = require('kpi_dashboard.widget_registry'); - var field_utils = require('web.field_utils'); + var IntegerWidget = require("kpi_dashboard.IntegerWidget"); + var registry = require("kpi_dashboard.widget_registry"); + var field_utils = require("web.field_utils"); var NumberWidget = IntegerWidget.extend({ digits: [3, 1], - shortNumber: function (num) { + shortNumber: function(num) { if (Math.abs(num) < 10) { return field_utils.format.float(num, false, { - digits: [3, 2]}); + digits: [3, 2], + }); } - return this._super.apply(this, arguments) + return this._super.apply(this, arguments); }, }); - registry.add('number', NumberWidget); + registry.add("number", NumberWidget); return NumberWidget; }); diff --git a/kpi_dashboard/static/src/js/widget/text_widget.js b/kpi_dashboard/static/src/js/widget/text_widget.js index 2af3774f..05efc517 100644 --- a/kpi_dashboard/static/src/js/widget/text_widget.js +++ b/kpi_dashboard/static/src/js/widget/text_widget.js @@ -1,17 +1,16 @@ -odoo.define('kpi_dashboard.TextWidget', function (require) { +odoo.define("kpi_dashboard.TextWidget", function(require) { "use strict"; - var AbstractWidget = require('kpi_dashboard.AbstractWidget'); - var registry = require('kpi_dashboard.widget_registry'); - + var AbstractWidget = require("kpi_dashboard.AbstractWidget"); + var registry = require("kpi_dashboard.widget_registry"); var TextWidget = AbstractWidget.extend({ - template: 'kpi_dashboard.base_text', - fillWidget: function () { + template: "kpi_dashboard.base_text", + fillWidget: function() { return; }, }); - registry.add('base_text', TextWidget); + registry.add("base_text", TextWidget); return TextWidget; }); diff --git a/kpi_dashboard/static/src/js/widget_registry.js b/kpi_dashboard/static/src/js/widget_registry.js index 1616886b..105a5a3a 100644 --- a/kpi_dashboard/static/src/js/widget_registry.js +++ b/kpi_dashboard/static/src/js/widget_registry.js @@ -1,7 +1,7 @@ -odoo.define('kpi_dashboard.widget_registry', function (require) { +odoo.define("kpi_dashboard.widget_registry", function(require) { "use strict"; - var Registry = require('web.Registry'); + var Registry = require("web.Registry"); return new Registry(); }); diff --git a/kpi_dashboard/static/src/scss/kpi_dashboard.scss b/kpi_dashboard/static/src/scss/kpi_dashboard.scss index fb580e2a..837252aa 100644 --- a/kpi_dashboard/static/src/scss/kpi_dashboard.scss +++ b/kpi_dashboard/static/src/scss/kpi_dashboard.scss @@ -1,11 +1,14 @@ .o_dashboard_view { height: 100%; - @include o-webclient-padding($top: $o-horizontal-padding/2, $bottom: $o-horizontal-padding/2); + @include o-webclient-padding( + $top: $o-horizontal-padding/2, + $bottom: $o-horizontal-padding/2 + ); display: flex; - >.gridster { + > .gridster { margin: 0 auto; - >ul { - >li { + > ul { + > li { text-align: center; list-style: none outside none; } @@ -56,7 +59,7 @@ max-width: 400px; } .o_kpi_dashboard_manage_section { - border-bottom: 1px solid gray('300'); + border-bottom: 1px solid gray("300"); margin-bottom: 10px; } > div { @@ -71,7 +74,7 @@ } .o_kpi_dashboard_toggle_button { background: white; - border-color: gray('400'); + border-color: gray("400"); z-index: $zindex-dropdown + 1; } } @@ -82,8 +85,9 @@ right: 0; overflow: hidden; cursor: default; - span, b{ - margin: 0 23%; + span, + b { + margin: 0 23%; width: 54%; position: absolute; text-align: center; @@ -93,20 +97,20 @@ white-space: nowrap; text-overflow: ellipsis; } - [data-style="Semi"] B{ - Margin: 0 10%; - Width: 80%; + [data-style="Semi"] b { + margin: 0 10%; + width: 80%; } - S, U{ - Text-Decoration:None; + s, + u { + text-decoration: None; font-height: 100; } - B{ - Color: Black; - Font-Weight: 200; - Font-Size: 0.85em; - Opacity: .8; + b { + color: Black; + font-weight: 200; + font-size: 0.85em; + opacity: 0.8; } } - } diff --git a/kpi_dashboard/static/src/xml/dashboard.xml b/kpi_dashboard/static/src/xml/dashboard.xml index 619d1853..e5de783f 100644 --- a/kpi_dashboard/static/src/xml/dashboard.xml +++ b/kpi_dashboard/static/src/xml/dashboard.xml @@ -2,11 +2,12 @@
-
    +
-
  • -

    +

    - + - + @@ -31,45 +38,55 @@
    -

    -

    +

    +

    - + + +

    - - + +

    -
    +
    -
    +
    diff --git a/kpi_dashboard/templates/assets.xml b/kpi_dashboard/templates/assets.xml index 87b5e141..70e78dc1 100644 --- a/kpi_dashboard/templates/assets.xml +++ b/kpi_dashboard/templates/assets.xml @@ -1,28 +1,68 @@ - + - -