[IMP] kpi_dashboard: black, isort, prettier

This commit is contained in:
Enric Tobella
2020-10-22 20:47:04 +02:00
parent 62b3a0393e
commit c90a783925
26 changed files with 955 additions and 845 deletions

View File

@@ -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 = $('<div/>');
this.$buttons.append(qweb.render(
"kpi_dashboard.buttons", {widget: this}));
this.$buttons = $("<div/>");
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;
});

View File

@@ -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;
});

View File

@@ -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) {

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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',
"/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',
],
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('<svg width=' + (self.widget_size_x - 20) + '>');
nv.addGraph(function() {
self.$svg = self.$el
.find('[data-bind="value"]')
.append("<svg width=" + (self.widget_size_x - 20) + ">");
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;
});

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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;
});

View File

@@ -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();
});

View File

@@ -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;
}
}
}

View File

@@ -2,11 +2,12 @@
<template>
<t t-name="dashboard_kpi.dashboard">
<div class="gridster kpi_dashboard">
<ul/>
<ul />
</div>
</t>
<t t-name="kpi_dashboard.kpi">
<li t-att-data-row="widget.row"
<li
t-att-data-row="widget.row"
t-att-data-col="widget.col"
t-att-data-sizex="widget.sizex"
t-att-data-sizey="widget.sizey"
@@ -14,15 +15,21 @@
</t>
<t t-name="kpi_dashboard.base_text">
<div class="kpi">
<h1 class="title" t-esc="widget.values.name"/>
<h1 class="title" t-esc="widget.values.name" />
</div>
</t>
<t t-name="kpi_dashboard.ManagePanel">
<t t-if="widget.actions" >
<t t-if="widget.actions">
<t t-foreach="widget.actions" t-as="action_id">
<t t-set="action" t-value="widget.actions[action_id]"/>
<t t-set="action" t-value="widget.actions[action_id]" />
<div role="menuitem" class="">
<a role="menuitem" href="#" class="direct_action" t-att-data-id="action_id" t-att-data-type="action.type">Go to <t t-esc="action.name"/></a>
<a
role="menuitem"
href="#"
class="direct_action"
t-att-data-id="action_id"
t-att-data-type="action.type"
>Go to <t t-esc="action.name" /></a>
</div>
</t>
</t>
@@ -31,45 +38,55 @@
<div class="kpi">
<div class="o_kpi_dashboard_manage hidden">
<a class="o_kpi_dashboard_toggle_button" href="#">
<i class="fa fa-ellipsis-v" aria-label="Selection" role="img" title="Selection"/>
<i
class="fa fa-ellipsis-v"
aria-label="Selection"
role="img"
title="Selection"
/>
</a>
</div>
<h1 class="title" t-esc="widget.values.name"/>
<p class="updated_at" data-bind="value_last_update_display"/>
<h1 class="title" t-esc="widget.values.name" />
<p class="updated_at" data-bind="value_last_update_display" />
<div class="container o_kpi_dashboard_manage_panel dropdown-menu">
<t t-call="kpi_dashboard.ManagePanel"/>
<t t-call="kpi_dashboard.ManagePanel" />
</div>
</div>
</t>
<t t-name="kpi_dashboard.number" t-extend="kpi_dashboard.base_widget">
<t t-jquery="h1" t-operation="after">
<h2 class="numbervalue">
<span t-esc="widget.prefix"/><span data-bind="value"/><span t-esc="widget.suffix"/>
<span t-esc="widget.prefix" />
<span data-bind="value" />
<span t-esc="widget.suffix" />
</h2>
<p class="change-rate">
<i class="fa" data-bind="arrow"/>
<span data-bind="difference"/>
<i class="fa" data-bind="arrow" />
<span data-bind="difference" />
</p>
</t>
</t>
<t t-name="kpi_dashboard.meter" t-extend="kpi_dashboard.base_widget">
<t t-jquery="h1" t-operation="after">
<div class="centered">
<div class="GaugeMeter" data-bind="value"/>
<div class="GaugeMeter" data-bind="value" />
</div>
</t>
</t>
<t t-name="kpi_dashboard.graph" t-extend="kpi_dashboard.base_widget">
<t t-jquery="h1" t-operation="after">
<div class="centered">
<div data-bind="value"/>
<div data-bind="value" />
</div>
</t>
</t>
<t t-name="kpi_dashboard.buttons">
<div class="o_dashboard_buttons" role="toolbar" aria-label="Main actions">
<button type="button"
class="btn btn-primary o_dashboard_button_add" accesskey="d">
<button
type="button"
class="btn btn-primary o_dashboard_button_add"
accesskey="d"
>
Add to Dashboard
</button>
</div>