commit
66006d4089
|
@ -15,8 +15,8 @@
|
||||||
"wizards/kpi_dashboard_menu.xml",
|
"wizards/kpi_dashboard_menu.xml",
|
||||||
"security/security.xml",
|
"security/security.xml",
|
||||||
"security/ir.model.access.csv",
|
"security/ir.model.access.csv",
|
||||||
|
"templates/assets.xml",
|
||||||
"views/kpi_menu.xml",
|
"views/kpi_menu.xml",
|
||||||
"views/webclient_templates.xml",
|
|
||||||
"views/kpi_kpi.xml",
|
"views/kpi_kpi.xml",
|
||||||
"views/kpi_dashboard.xml",
|
"views/kpi_dashboard.xml",
|
||||||
],
|
],
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<field name="widget_dimension_y">50</field>
|
<field name="widget_dimension_y">50</field>
|
||||||
<field name="widget_dimension_x">250</field>
|
<field name="widget_dimension_x">250</field>
|
||||||
<field name="background_color">#020202</field>
|
<field name="background_color">#020202</field>
|
||||||
|
<field name="compute_on_fly_refresh">30</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="widget_number_01" model="kpi.kpi">
|
<record id="widget_number_01" model="kpi.kpi">
|
||||||
|
@ -87,6 +88,26 @@ result = {"graphs": [
|
||||||
<function model="kpi.kpi" name="compute"
|
<function model="kpi.kpi" name="compute"
|
||||||
eval="[[ref('widget_graph')]]"/>
|
eval="[[ref('widget_graph')]]"/>
|
||||||
|
|
||||||
|
<record id="widget_integer" model="kpi.kpi">
|
||||||
|
<field name="name">Integer counter</field>
|
||||||
|
<field name="computation_method">code</field>
|
||||||
|
<field name="widget">integer</field>
|
||||||
|
<field name="compute_on_fly" eval="True"/>
|
||||||
|
<field name="code">
|
||||||
|
result = {"value": self.env.context.get('counter', 990)}
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="widget_counter" model="kpi.kpi">
|
||||||
|
<field name="name">Counter</field>
|
||||||
|
<field name="computation_method">code</field>
|
||||||
|
<field name="widget">counter</field>
|
||||||
|
<field name="compute_on_fly" eval="True"/>
|
||||||
|
<field name="code">
|
||||||
|
result = {"value": self.env.context.get('counter', 990)}
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record id="dashboard_widget_text" model="kpi.dashboard.item">
|
<record id="dashboard_widget_text" model="kpi.dashboard.item">
|
||||||
<field name="name">Dashboard title</field>
|
<field name="name">Dashboard title</field>
|
||||||
<field name="dashboard_id" ref="demo_dashboard"/>
|
<field name="dashboard_id" ref="demo_dashboard"/>
|
||||||
|
@ -141,6 +162,43 @@ result = {"graphs": [
|
||||||
<field name="font_color">#ffffff</field>
|
<field name="font_color">#ffffff</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="dashboard_widget_add_counter" model="kpi.dashboard.item">
|
||||||
|
<field name="name">+1 to Counter</field>
|
||||||
|
<field name="dashboard_id" ref="demo_dashboard"/>
|
||||||
|
<field name="column">3</field>
|
||||||
|
<field name="row">10</field>
|
||||||
|
<field name="size_y">1</field>
|
||||||
|
<field name="size_x">2</field>
|
||||||
|
<field name="color">#B41F1F</field>
|
||||||
|
<field name="font_color">#EEBF77</field>
|
||||||
|
<field name="modify_context" eval="True"/>
|
||||||
|
<field name="modify_context_expression">{'counter': (context.counter or 990) + 1}</field>
|
||||||
|
<field name="modify_color" eval="True"/>
|
||||||
|
<field name="modify_color_expression">check_if(((context.counter or 990) + 1) % 2, '#ff0000', '#00ff00')</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="dashboard_widget_counter" model="kpi.dashboard.item">
|
||||||
|
<field name="name">Counter</field>
|
||||||
|
<field name="dashboard_id" ref="demo_dashboard"/>
|
||||||
|
<field name="kpi_id" ref="widget_counter"/>
|
||||||
|
<field name="column">3</field>
|
||||||
|
<field name="row">11</field>
|
||||||
|
<field name="size_y">3</field>
|
||||||
|
<field name="color">#4B0082</field>
|
||||||
|
<field name="font_color">#ffffff</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="dashboard_widget_integer" model="kpi.dashboard.item">
|
||||||
|
<field name="name">Integer</field>
|
||||||
|
<field name="dashboard_id" ref="demo_dashboard"/>
|
||||||
|
<field name="kpi_id" ref="widget_integer"/>
|
||||||
|
<field name="column">4</field>
|
||||||
|
<field name="row">11</field>
|
||||||
|
<field name="size_y">3</field>
|
||||||
|
<field name="color">#ffffff</field>
|
||||||
|
<field name="font_color">#4B0082</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record id="dashboard_widget_graph" model="kpi.dashboard.item">
|
<record id="dashboard_widget_graph" model="kpi.dashboard.item">
|
||||||
<field name="name">Graph</field>
|
<field name="name">Graph</field>
|
||||||
<field name="dashboard_id" ref="demo_dashboard"/>
|
<field name="dashboard_id" ref="demo_dashboard"/>
|
||||||
|
|
|
@ -117,6 +117,10 @@ class KpiDashboardItem(models.Model):
|
||||||
size_y = fields.Integer(required=True, default=1)
|
size_y = fields.Integer(required=True, default=1)
|
||||||
color = fields.Char()
|
color = fields.Char()
|
||||||
font_color = fields.Char()
|
font_color = fields.Char()
|
||||||
|
modify_context = fields.Boolean()
|
||||||
|
modify_context_expression = fields.Char()
|
||||||
|
modify_color = fields.Boolean()
|
||||||
|
modify_color_expression = fields.Char()
|
||||||
|
|
||||||
@api.depends('row', 'size_y')
|
@api.depends('row', 'size_y')
|
||||||
def _compute_end_row(self):
|
def _compute_end_row(self):
|
||||||
|
@ -173,7 +177,13 @@ class KpiDashboardItem(models.Model):
|
||||||
"sizey": self.size_y,
|
"sizey": self.size_y,
|
||||||
"color": self.color,
|
"color": self.color,
|
||||||
"font_color": self.font_color or "000000",
|
"font_color": self.font_color or "000000",
|
||||||
|
"modify_context": self.modify_context,
|
||||||
|
"modify_color": self.modify_color,
|
||||||
}
|
}
|
||||||
|
if self.modify_context:
|
||||||
|
vals['modify_context_expression'] = self.modify_context_expression
|
||||||
|
if self.modify_color:
|
||||||
|
vals['modify_color_expression'] = self.modify_color_expression
|
||||||
if self.kpi_id:
|
if self.kpi_id:
|
||||||
vals.update(
|
vals.update(
|
||||||
{
|
{
|
||||||
|
@ -205,3 +215,16 @@ class KpiDashboardItem(models.Model):
|
||||||
for kpi in self:
|
for kpi in self:
|
||||||
result.append(kpi._read_dashboard())
|
result.append(kpi._read_dashboard())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ from odoo.tools.float_utils import float_compare
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
|
from dateutil import relativedelta
|
||||||
|
|
||||||
|
|
||||||
class KpiKpi(models.Model):
|
class KpiKpi(models.Model):
|
||||||
|
@ -29,7 +30,8 @@ class KpiKpi(models.Model):
|
||||||
args = fields.Char()
|
args = fields.Char()
|
||||||
kwargs = fields.Char()
|
kwargs = fields.Char()
|
||||||
widget = fields.Selection(
|
widget = fields.Selection(
|
||||||
[("number", "Number"), ("meter", "Meter"), ("graph", "Graph")],
|
[('integer', 'Integer'), ("number", "Number"), ("meter", "Meter"),
|
||||||
|
('counter', 'Counter'), ("graph", "Graph")],
|
||||||
required=True,
|
required=True,
|
||||||
default="number",
|
default="number",
|
||||||
)
|
)
|
||||||
|
@ -136,6 +138,7 @@ class KpiKpi(models.Model):
|
||||||
"model": self.browse(),
|
"model": self.browse(),
|
||||||
"datetime": datetime,
|
"datetime": datetime,
|
||||||
"float_compare": float_compare,
|
"float_compare": float_compare,
|
||||||
|
"relativedelta": relativedelta.relativedelta,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _forbidden_code(self):
|
def _forbidden_code(self):
|
||||||
|
|
|
@ -8,9 +8,17 @@ odoo.define('kpi_dashboard.DashboardController', function (require) {
|
||||||
var _t = core._t;
|
var _t = core._t;
|
||||||
|
|
||||||
var DashboardController = BasicController.extend({
|
var DashboardController = BasicController.extend({
|
||||||
|
init: function () {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.dashboard_context = {};
|
||||||
|
this.dashboard_color_data = []
|
||||||
|
},
|
||||||
custom_events: _.extend({}, BasicController.prototype.custom_events, {
|
custom_events: _.extend({}, BasicController.prototype.custom_events, {
|
||||||
addDashboard: '_addDashboard',
|
addDashboard: '_addDashboard',
|
||||||
refresh_on_fly: '_refreshOnFly',
|
refresh_on_fly: '_refreshOnFly',
|
||||||
|
modify_context: '_modifyContext',
|
||||||
|
add_modify_color: '_addModifyColor',
|
||||||
|
refresh_colors: '_refreshColors',
|
||||||
}),
|
}),
|
||||||
_refreshOnFly: function (event) {
|
_refreshOnFly: function (event) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -18,11 +26,7 @@ odoo.define('kpi_dashboard.DashboardController', function (require) {
|
||||||
model: this.modelName,
|
model: this.modelName,
|
||||||
method: 'read_dashboard_on_fly',
|
method: 'read_dashboard_on_fly',
|
||||||
args: [[this.renderer.state.res_id]],
|
args: [[this.renderer.state.res_id]],
|
||||||
context: _.extend(
|
context: this._getContext(),
|
||||||
{},
|
|
||||||
this.model.get(this.handle, {raw: true}).getContext(),
|
|
||||||
{bin_size: true}
|
|
||||||
),
|
|
||||||
}).then(function (data) {
|
}).then(function (data) {
|
||||||
_.each(data, function (item) {
|
_.each(data, function (item) {
|
||||||
// We will follow the same logic used on Bus Notifications
|
// We will follow the same logic used on Bus Notifications
|
||||||
|
@ -91,6 +95,54 @@ odoo.define('kpi_dashboard.DashboardController', function (require) {
|
||||||
this._updateButtons();
|
this._updateButtons();
|
||||||
this.$buttons.appendTo($node);
|
this.$buttons.appendTo($node);
|
||||||
},
|
},
|
||||||
|
_getContext: function () {
|
||||||
|
return _.extend(
|
||||||
|
{},
|
||||||
|
this.model.get(this.handle, {raw: true}).getContext(),
|
||||||
|
{bin_size: true},
|
||||||
|
this.dashboard_context,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_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
|
||||||
|
)}),
|
||||||
|
);
|
||||||
|
this._refreshOnFly(event);
|
||||||
|
this._refreshColors();
|
||||||
|
},
|
||||||
|
_addModifyColor: function (event) {
|
||||||
|
this.dashboard_color_data.push([
|
||||||
|
event.data.element_id,
|
||||||
|
event.data.expression,
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
_refreshColors: function () {
|
||||||
|
var self = this;
|
||||||
|
var ctx = this._getContext();
|
||||||
|
_.each(this.dashboard_color_data, function (data) {
|
||||||
|
var color = py.eval(data[1], {
|
||||||
|
context: _.extend(ctx, {
|
||||||
|
__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);
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return DashboardController;
|
return DashboardController;
|
||||||
|
|
|
@ -16,6 +16,12 @@ odoo.define('kpi_dashboard.DashboardRenderer', function (require) {
|
||||||
var widget = new Widget(this, kpi);
|
var widget = new Widget(this, kpi);
|
||||||
return widget;
|
return widget;
|
||||||
},
|
},
|
||||||
|
_onClickModifyContext: function (modify_context_expression, event) {
|
||||||
|
this.trigger_up('modify_context', {
|
||||||
|
context: modify_context_expression,
|
||||||
|
event: event,
|
||||||
|
})
|
||||||
|
},
|
||||||
_renderView: function () {
|
_renderView: function () {
|
||||||
this.$el.html($(qweb.render('dashboard_kpi.dashboard')));
|
this.$el.html($(qweb.render('dashboard_kpi.dashboard')));
|
||||||
this.$el.css(
|
this.$el.css(
|
||||||
|
@ -30,7 +36,20 @@ odoo.define('kpi_dashboard.DashboardRenderer', function (require) {
|
||||||
'kpi_dashboard.kpi', {widget: kpi}));
|
'kpi_dashboard.kpi', {widget: kpi}));
|
||||||
element.css('background-color', kpi.color);
|
element.css('background-color', kpi.color);
|
||||||
element.css('color', kpi.font_color);
|
element.css('color', kpi.font_color);
|
||||||
|
element.attr('id', _.uniqueId('kpi_'));
|
||||||
self.$grid.append(element);
|
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');
|
||||||
|
// We want to set it show as clickable
|
||||||
|
}
|
||||||
self.kpi_widget[kpi.id] = self._getDashboardWidget(kpi);
|
self.kpi_widget[kpi.id] = self._getDashboardWidget(kpi);
|
||||||
self.kpi_widget[kpi.id].appendTo(element);
|
self.kpi_widget[kpi.id].appendTo(element);
|
||||||
});
|
});
|
||||||
|
@ -59,6 +78,10 @@ odoo.define('kpi_dashboard.DashboardRenderer', function (require) {
|
||||||
self.trigger_up('refresh_on_fly');
|
self.trigger_up('refresh_on_fly');
|
||||||
}, this.state.specialData.compute_on_fly_refresh *1000);
|
}, 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();
|
return $.when();
|
||||||
},
|
},
|
||||||
on_detach_callback: function () {
|
on_detach_callback: function () {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
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 CounterWidget = IntegerWidget.extend({
|
||||||
|
shortList: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
registry.add('counter', CounterWidget);
|
||||||
|
return CounterWidget;
|
||||||
|
});
|
|
@ -0,0 +1,71 @@
|
||||||
|
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 IntegerWidget = AbstractWidget.extend({
|
||||||
|
template: 'kpi_dashboard.number',
|
||||||
|
digits: [3, 0],
|
||||||
|
shortList: [
|
||||||
|
[1000000000000, 'T', [3, 1]],
|
||||||
|
[1000000000, 'G', [3, 1]],
|
||||||
|
[1000000, 'M', [3, 1]],
|
||||||
|
[1000, 'K', [3, 1]]
|
||||||
|
],
|
||||||
|
shortNumber: function (num) {
|
||||||
|
var suffix = '';
|
||||||
|
var shortened = false;
|
||||||
|
var digits = this.digits;
|
||||||
|
_.each(this.shortList, function (shortItem) {
|
||||||
|
if (!shortened && Math.abs(num) >= shortItem[0]) {
|
||||||
|
shortened = true;
|
||||||
|
suffix = shortItem[1];
|
||||||
|
num = num / shortItem[0];
|
||||||
|
digits = shortItem[2];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return field_utils.format.float(num, false, {
|
||||||
|
digits: digits}) + suffix;
|
||||||
|
},
|
||||||
|
fillWidget: function (values) {
|
||||||
|
var widget = this.$el;
|
||||||
|
var value = values.value.value;
|
||||||
|
if (value === undefined) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
var item = widget.find('[data-bind="value"]');
|
||||||
|
if (item) {
|
||||||
|
item.text(this.shortNumber(value));
|
||||||
|
}
|
||||||
|
var previous = values.value.previous;
|
||||||
|
|
||||||
|
var $change_rate = widget.find('.change-rate');
|
||||||
|
if (previous === undefined) {
|
||||||
|
$change_rate.toggleClass('active', false);
|
||||||
|
} else {
|
||||||
|
var difference = 0;
|
||||||
|
if (previous !== 0) {
|
||||||
|
difference = field_utils.format.integer(
|
||||||
|
(100 * value / previous) - 100) + '%';
|
||||||
|
}
|
||||||
|
$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);
|
||||||
|
} else {
|
||||||
|
$arrow.toggleClass('fa-arrow-up', true);
|
||||||
|
$arrow.toggleClass('fa-arrow-down', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
registry.add('integer', IntegerWidget);
|
||||||
|
return IntegerWidget;
|
||||||
|
});
|
|
@ -1,72 +1,21 @@
|
||||||
odoo.define('kpi_dashboard.NumberWidget', function (require) {
|
odoo.define('kpi_dashboard.NumberWidget', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var AbstractWidget = require('kpi_dashboard.AbstractWidget');
|
var IntegerWidget = require('kpi_dashboard.IntegerWidget');
|
||||||
var registry = require('kpi_dashboard.widget_registry');
|
var registry = require('kpi_dashboard.widget_registry');
|
||||||
var field_utils = require('web.field_utils');
|
var field_utils = require('web.field_utils');
|
||||||
|
|
||||||
|
var NumberWidget = IntegerWidget.extend({
|
||||||
var NumberWidget = AbstractWidget.extend({
|
digits: [3, 1],
|
||||||
template: 'kpi_dashboard.number',
|
|
||||||
shortNumber: function (num) {
|
shortNumber: function (num) {
|
||||||
if (Math.abs(num) >= 1000000000000) {
|
if (Math.abs(num) < 10) {
|
||||||
return field_utils.format.integer(num / 1000000000000, false, {
|
|
||||||
digits: [3, 1]}) + 'T';
|
|
||||||
}
|
|
||||||
if (Math.abs(num) >= 1000000000) {
|
|
||||||
return field_utils.format.integer(num / 1000000000, false, {
|
|
||||||
digits: [3,1]}) + 'G';
|
|
||||||
}
|
|
||||||
if (Math.abs(num) >= 1000000) {
|
|
||||||
return field_utils.format.integer(num / 1000000, false, {
|
|
||||||
digits: [3, 1]}) + 'M';
|
|
||||||
}
|
|
||||||
if (Math.abs(num) >= 1000) {
|
|
||||||
return field_utils.format.float(num / 1000, false, {
|
|
||||||
digits: [3, 1]}) + 'K';
|
|
||||||
}
|
|
||||||
if (Math.abs(num) >= 10) {
|
|
||||||
return field_utils.format.float(num, false, {
|
return field_utils.format.float(num, false, {
|
||||||
digits: [3, 1]});
|
digits: [3, 2]});
|
||||||
}
|
|
||||||
return field_utils.format.float(num, false, {
|
|
||||||
digits: [3, 2]});
|
|
||||||
},
|
|
||||||
fillWidget: function (values) {
|
|
||||||
var widget = this.$el;
|
|
||||||
var value = values.value.value;
|
|
||||||
if (value === undefined) {
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
var item = widget.find('[data-bind="value"]');
|
|
||||||
if (item) {
|
|
||||||
item.text(this.shortNumber(value));
|
|
||||||
}
|
|
||||||
var previous = values.value.previous;
|
|
||||||
|
|
||||||
var $change_rate = widget.find('.change-rate');
|
|
||||||
if (previous === undefined) {
|
|
||||||
$change_rate.toggleClass('active', false);
|
|
||||||
} else {
|
|
||||||
var difference = 0;
|
|
||||||
if (previous !== 0) {
|
|
||||||
difference = field_utils.format.integer(
|
|
||||||
(100 * value / previous) - 100) + '%';
|
|
||||||
}
|
|
||||||
$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);
|
|
||||||
} else {
|
|
||||||
$arrow.toggleClass('fa-arrow-up', true);
|
|
||||||
$arrow.toggleClass('fa-arrow-down', false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return this._super.apply(this, arguments)
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
registry.add('number', NumberWidget);
|
registry.add('number', NumberWidget);
|
||||||
return NumberWidget;
|
return NumberWidget;
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
<script type="text/javascript" src="/kpi_dashboard/static/src/js/dashboard_controller.js"/>
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/dashboard_controller.js"/>
|
||||||
<script type="text/javascript" src="/kpi_dashboard/static/src/js/dashboard_view.js"/>
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/dashboard_view.js"/>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/integer_widget.js"/>
|
||||||
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/number_widget.js"/>
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/number_widget.js"/>
|
||||||
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/counter_widget.js"/>
|
||||||
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/meter_widget.js"/>
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/meter_widget.js"/>
|
||||||
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/graph_widget.js"/>
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/graph_widget.js"/>
|
||||||
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/text_widget.js"/>
|
<script type="text/javascript" src="/kpi_dashboard/static/src/js/widget/text_widget.js"/>
|
|
@ -36,6 +36,9 @@
|
||||||
<field name="size_y"/>
|
<field name="size_y"/>
|
||||||
<field name="color" widget="color"/>
|
<field name="color" widget="color"/>
|
||||||
<field name="font_color" widget="color"/>
|
<field name="font_color" widget="color"/>
|
||||||
|
<button name="technical_config" string=""
|
||||||
|
type="object" icon="fa-edit"
|
||||||
|
groups="base.group_no_one"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
|
@ -111,4 +114,57 @@
|
||||||
<field name="sequence" eval="16"/> <!-- TODO -->
|
<field name="sequence" eval="16"/> <!-- TODO -->
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="kpi_dashboard_item_form_view">
|
||||||
|
<field name="name">kpi.dashboard.item.form (in kpi_dashboard)</field>
|
||||||
|
<field name="model">kpi.dashboard.item</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<header/>
|
||||||
|
<sheet>
|
||||||
|
<div name="button_box" class="oe_button_box"/>
|
||||||
|
<group>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="dashboard_id"/>
|
||||||
|
<field name="kpi_id"/>
|
||||||
|
<field name="column"/>
|
||||||
|
<field name="row"/>
|
||||||
|
<field name="size_x"/>
|
||||||
|
<field name="size_y"/>
|
||||||
|
<field name="color" widget="color"/>
|
||||||
|
<field name="font_color" widget="color"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="kpi_dashboard_item_config_form_view">
|
||||||
|
<field name="name">kpi.dashboard.item.form (in kpi_dashboard)</field>
|
||||||
|
<field name="model">kpi.dashboard.item</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<header/>
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="modify_context"/>
|
||||||
|
<field name="modify_context_expression"
|
||||||
|
attrs="{'invisible': [('modify_context', '=', False)]}"
|
||||||
|
widget="ace" options="{'mode': 'python'}"/>
|
||||||
|
<field name="modify_color"/>
|
||||||
|
<field name="modify_color_expression"
|
||||||
|
attrs="{'invisible': [('modify_color', '=', False)]}"
|
||||||
|
widget="ace" options="{'mode': 'python'}"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
<footer>
|
||||||
|
<button name="write"
|
||||||
|
string="Save" type="object"
|
||||||
|
class="oe_highlight"/>
|
||||||
|
<button special="cancel" string="Cancel"
|
||||||
|
class="oe_link"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
Loading…
Reference in New Issue