pre-commit

This commit is contained in:
Andrea
2020-09-09 12:52:32 +02:00
parent 2d17441547
commit fb5ba3bce4
17 changed files with 1368 additions and 1093 deletions

View File

@@ -1,9 +1,10 @@
.oe_form_field_bi_editor {
/*box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);*/
border: 1px solid #DDDDDD;
border: 1px solid #dddddd;
}
.oe_form_field_bi_editor .header, .oe_form_field_bi_editor .footer {
.oe_form_field_bi_editor .header,
.oe_form_field_bi_editor .footer {
width: 100%;
height: 50px;
background-color: #7c7bad;
@@ -11,11 +12,12 @@
}
.oe_form_field_bi_editor .footer {
background-color: #FFF;
border-top: 1px solid #DDDDDD;
background-color: #fff;
border-top: 1px solid #dddddd;
}
.oe_form_field_bi_editor .header .left, .oe_form_field_bi_editor .footer .left {
.oe_form_field_bi_editor .header .left,
.oe_form_field_bi_editor .footer .left {
width: 75%;
float: left;
line-height: 50px;
@@ -23,7 +25,8 @@
padding-top: 13px;
}
.oe_form_field_bi_editor .header .right, .oe_form_field_bi_editor .footer .right {
.oe_form_field_bi_editor .header .right,
.oe_form_field_bi_editor .footer .right {
width: 25%;
float: right;
padding-top: 13px;
@@ -39,7 +42,7 @@
float: left;
width: 30%;
box-sizing: border-box;
border-right: 1px solid #DDDDDD;
border-right: 1px solid #dddddd;
}
.oe_form_field_bi_editor .body .left .search-bar {
@@ -84,19 +87,19 @@
}
.oe_form_field_bi_editor .body .left .class-list.readonly {
opacity: .35;
opacity: 0.35;
}
.oe_form_field_bi_editor .body .left .class-list .class.readonly {
cursor: default;
}
.oe_form_field_bi_editor .body .left .class-list .class:hover {
background-color: #7C7BAD;
color: #FFF;
.oe_form_field_bi_editor .body .left .class-list .class:hover {
background-color: #7c7bad;
color: #fff;
}
.oe_form_field_bi_editor .body .left .class-list .field {
.oe_form_field_bi_editor .body .left .class-list .field {
font-weight: normal;
padding-left: 20px;
padding-top: 3px;
@@ -113,12 +116,12 @@
overflow-x: hidden;
}
.oe_form_field_bi_editor .body .right .field-list {
.oe_form_field_bi_editor .body .right .field-list {
width: 100%;
}
.oe_form_field_bi_editor .body .right .field-list th,
.oe_form_field_bi_editor .body .right .field-list td {
.oe_form_field_bi_editor .body .right .field-list th,
.oe_form_field_bi_editor .body .right .field-list td {
padding-left: 10px;
padding-top: 6px;
padding-bottom: 6px;
@@ -130,26 +133,27 @@
background-color: transparent;
border: none;
background-image: none;
padding: 0;
cursor: pointer;
padding: 0;
cursor: pointer;
}
.oe_form_field_bi_editor .body .right .field-list tbody tr:hover {
background-color: #DDD;
background-color: #ddd;
}
.oe_form_field_bi_editor .body .right .field-list tbody tr.join-node {
background-color: #D2D2FF;
background-color: #d2d2ff;
text-align: center;
border-top: 1px solid #DDDDDD;
border-top: 1px solid #dddddd;
}
.oe_form_field_bi_editor .context-menu, .oe_form_field_bi_editor .context-menu ul {
.oe_form_field_bi_editor .context-menu,
.oe_form_field_bi_editor .context-menu ul {
z-index: 1000;
position: fixed;
background-color: #fff;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
border: 1px solid #DDDDDD;
border: 1px solid #dddddd;
list-style-type: none;
padding: 0;
width: 175px;
@@ -174,8 +178,8 @@
}
.oe_form_field_bi_editor .context-menu li:hover {
background-color: #7C7BAD;
color: #FFF;
background-color: #7c7bad;
color: #fff;
}
.oe_form_field_bi_editor .context-menu ul {
@@ -196,4 +200,4 @@
.oe_bi_view_editor_join_node_dialog li {
cursor: pointer;
}
}

View File

@@ -1,57 +1,55 @@
/* Copyright 2015-2019 Onestein (<https://www.onestein.eu>)
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('bi_view_editor.FieldList', function (require) {
odoo.define("bi_view_editor.FieldList", function(require) {
"use strict";
var core = require('web.core');
var core = require("web.core");
var qweb = core.qweb;
var Widget = require('web.Widget');
var Widget = require("web.Widget");
var FieldListContextMenu = Widget.extend({
start: function () {
start: function() {
var res = this._super.apply(this, arguments);
this.$el.mouseleave(function () {
$(this).addClass('d-none');
this.$el.mouseleave(function() {
$(this).addClass("d-none");
});
return res;
},
open: function (x, y) {
open: function(x, y) {
this.$el.css({
'left': x + 'px',
'top': y + 'px',
left: x + "px",
top: y + "px",
});
this.$el.removeClass('d-none');
this.$el.removeClass("d-none");
return _.extend({}, window.Backbone.Events);
},
});
var FieldListFieldContextMenu = FieldListContextMenu.extend({
template: 'bi_view_editor.FieldList.FieldContextMenu',
open: function (x, y, field) {
this.$el.find('.checkbox-column').prop('checked', field.column);
this.$el.find('.checkbox-row').prop('checked', field.row);
this.$el.find('.checkbox-measure').prop('checked', field.measure);
this.$el.find('.checkbox-list').prop('checked', field.list);
template: "bi_view_editor.FieldList.FieldContextMenu",
open: function(x, y, field) {
this.$el.find(".checkbox-column").prop("checked", field.column);
this.$el.find(".checkbox-row").prop("checked", field.row);
this.$el.find(".checkbox-measure").prop("checked", field.measure);
this.$el.find(".checkbox-list").prop("checked", field.list);
var measureable =
field.type === "float" ||
field.type === "integer" ||
field.type === "monetary"
;
this.$el.find('.checkbox-column').attr('disabled', measureable);
this.$el.find('.checkbox-row').attr('disabled', measureable);
this.$el.find('.checkbox-measure').attr('disabled', !measureable);
this.$el.find('.checkbox-list').attr('disabled', false);
field.type === "monetary";
this.$el.find(".checkbox-column").attr("disabled", measureable);
this.$el.find(".checkbox-row").attr("disabled", measureable);
this.$el.find(".checkbox-measure").attr("disabled", !measureable);
this.$el.find(".checkbox-list").attr("disabled", false);
var events = this._super(x, y, field);
this.$el.find('input').unbind('change');
this.$el.find('input').change(function () {
this.$el.find("input").unbind("change");
this.$el.find("input").change(function() {
var $checkbox = $(this);
var property = $checkbox.attr('data-for');
field[property] = $checkbox.is(':checked');
events.trigger('change', field);
var property = $checkbox.attr("data-for");
field[property] = $checkbox.is(":checked");
events.trigger("change", field);
});
return events;
@@ -59,67 +57,71 @@ odoo.define('bi_view_editor.FieldList', function (require) {
});
var FieldListJoinContextMenu = FieldListContextMenu.extend({
template: 'bi_view_editor.FieldList.JoinContextMenu',
open: function (x, y, node) {
this.$el.find('.checkbox-join-left').prop('checked', node.join_left);
template: "bi_view_editor.FieldList.JoinContextMenu",
open: function(x, y, node) {
this.$el.find(".checkbox-join-left").prop("checked", node.join_left);
var events = this._super(x, y, node);
this.$el.find('input').unbind('change');
this.$el.find('input').change(function () {
this.$el.find("input").unbind("change");
this.$el.find("input").change(function() {
var $checkbox = $(this);
var property = $checkbox.attr('data-for');
node[property] = $checkbox.is(':checked');
events.trigger('change', node);
var property = $checkbox.attr("data-for");
node[property] = $checkbox.is(":checked");
events.trigger("change", node);
});
return events;
},
});
var FieldList = Widget.extend({
template: 'bi_view_editor.FieldList',
template: "bi_view_editor.FieldList",
events: {
'click .delete-button': 'removeClicked',
'keyup input[name="description"]': 'keyupDescription',
"click .delete-button": "removeClicked",
'keyup input[name="description"]': "keyupDescription",
},
start: function () {
start: function() {
var res = this._super.apply(this, arguments);
this.contextmenu = new FieldListFieldContextMenu(this);
this.contextmenu.appendTo(this.$el);
this.contextmenu_join = new FieldListJoinContextMenu(this);
this.contextmenu_join.appendTo(this.$el);
this.$table = this.$el.find('tbody');
this.$table = this.$el.find("tbody");
this.mode = null;
return res;
},
setMode: function (mode) {
if (mode === 'readonly') {
this.$el.find('input[type="text"]').attr('disabled', true);
this.$el.find(".delete-button").addClass('d-none');
setMode: function(mode) {
if (mode === "readonly") {
this.$el.find('input[type="text"]').attr("disabled", true);
this.$el.find(".delete-button").addClass("d-none");
} else {
this.$el.find('input[type="text"]').removeAttr('disabled');
this.$el.find(".delete-button").removeClass('d-none');
this.$el.find('input[type="text"]').removeAttr("disabled");
this.$el.find(".delete-button").removeClass("d-none");
}
this.mode = mode;
},
get: function () {
return $.makeArray(this.$el.find("tbody tr").map(function () {
var field = $(this).data('field');
field.description = $(this).find('input[name="description"]').val();
return field;
}));
get: function() {
return $.makeArray(
this.$el.find("tbody tr").map(function() {
var field = $(this).data("field");
field.description = $(this)
.find('input[name="description"]')
.val();
return field;
})
);
},
getModelIds: function () {
getModelIds: function() {
var model_ids = {};
this.$el.find("tbody tr").each(function () {
var data = $(this).data('field');
this.$el.find("tbody tr").each(function() {
var data = $(this).data("field");
model_ids[data.table_alias] = data.model_id;
});
return model_ids;
},
getModelData: function () {
getModelData: function() {
var model_data = {};
this.$el.find("tbody tr").each(function () {
var data = $(this).data('field');
this.$el.find("tbody tr").each(function() {
var data = $(this).data("field");
model_data[data.table_alias] = {
model_id: data.model_id,
model_name: data.model_name,
@@ -127,95 +129,114 @@ odoo.define('bi_view_editor.FieldList', function (require) {
});
return model_data;
},
add: function (field) {
add: function(field) {
var self = this;
field.row = typeof field.row === 'undefined' ? false : field.row;
field.column = typeof field.column === 'undefined' ? false : field.column;
field.measure = typeof field.measure === 'undefined' ? false : field.measure;
field.list = typeof field.list === 'undefined' ? true : field.list;
field._id = typeof field._id === 'undefined' ? _.uniqueId('node_') : field._id;
field.row = typeof field.row === "undefined" ? false : field.row;
field.column = typeof field.column === "undefined" ? false : field.column;
field.measure =
typeof field.measure === "undefined" ? false : field.measure;
field.list = typeof field.list === "undefined" ? true : field.list;
field._id =
typeof field._id === "undefined" ? _.uniqueId("node_") : field._id;
if (field.join_node) {
field.join_left = typeof field.join_left === 'undefined' ? false : field.join_left;
field.join_left =
typeof field.join_left === "undefined" ? false : field.join_left;
}
var i = 0;
var name = field.name;
while (this.get().filter(function (item) {
return item.name === field.name;
}).length > 0) {
field.name = name + '_' + i;
while (
this.get().filter(function(item) {
return item.name === field.name;
}).length > 0
) {
field.name = name + "_" + i;
i++;
}
// Render table row
var $html = $(qweb.render(field.join_node ? 'bi_view_editor.JoinListItem' : 'bi_view_editor.FieldListItem', {
'field': field,
})).data('field', field).contextmenu(function (e) {
var $item = $(this);
if (self.mode === 'readonly') {
return;
}
e.preventDefault();
self.openContextMenu($item, e.pageX, e.pageY);
});
var $html = $(
qweb.render(
field.join_node
? "bi_view_editor.JoinListItem"
: "bi_view_editor.FieldListItem",
{
field: field,
}
)
)
.data("field", field)
.contextmenu(function(e) {
var $item = $(this);
if (self.mode === "readonly") {
return;
}
e.preventDefault();
self.openContextMenu($item, e.pageX, e.pageY);
});
this.$el.find('tbody').append($html);
this.$el.find("tbody").append($html);
},
remove: function (id) {
remove: function(id) {
var $item = this.$el.find('tr[data-id="' + id + '"]');
$item.remove();
this.trigger('removed', id);
this.trigger("removed", id);
},
set: function (fields) {
set: function(fields) {
var set_fields = fields;
if (!set_fields) {
set_fields = [];
}
this.$el.find('tbody tr').remove();
this.$el.find("tbody tr").remove();
for (var i = 0; i < set_fields.length; i++) {
this.add(set_fields[i]);
}
},
openContextMenu: function ($item, x, y) {
var field = $item.data('field');
var contextmenu = field.join_node ? this.contextmenu_join : this.contextmenu;
openContextMenu: function($item, x, y) {
var field = $item.data("field");
var contextmenu = field.join_node
? this.contextmenu_join
: this.contextmenu;
// Temporary disable contextmenu for join node (until left join is implemented)
if (field.join_node) {
return;
}
contextmenu.open(x - 20, y - 20, $item.data('field')).on('change', function (f) {
$item.data('field', f);
this.refreshItem($item);
this.trigger('updated');
}.bind(this));
contextmenu.open(x - 20, y - 20, $item.data("field")).on(
"change",
function(f) {
$item.data("field", f);
this.refreshItem($item);
this.trigger("updated");
}.bind(this)
);
},
refreshItem: function ($item) {
var data = $item.data('field');
var $attributes = $item.find('span[data-for], img[data-for]');
$.each($attributes, function () {
refreshItem: function($item) {
var data = $item.data("field");
var $attributes = $item.find("span[data-for], img[data-for]");
$.each($attributes, function() {
var $attribute = $(this);
var value = data[$attribute.attr('data-for')];
var value = data[$attribute.attr("data-for")];
if (value) {
$attribute.removeClass('d-none');
$attribute.removeClass("d-none");
} else {
$attribute.addClass('d-none');
$attribute.addClass("d-none");
}
});
},
removeClicked: function (e) {
removeClicked: function(e) {
var $button = $(e.currentTarget);
var id = $button.attr('data-id');
var id = $button.attr("data-id");
this.remove(id);
},
keyupDescription: function () {
this.trigger('updated');
keyupDescription: function() {
this.trigger("updated");
},
});
return {
'FieldList': FieldList,
'FieldListContextMenu': FieldListContextMenu,
'FieldListFieldContextMenu': FieldListFieldContextMenu,
'FieldListJoinContextMenu': FieldListJoinContextMenu,
FieldList: FieldList,
FieldListContextMenu: FieldListContextMenu,
FieldListFieldContextMenu: FieldListFieldContextMenu,
FieldListJoinContextMenu: FieldListJoinContextMenu,
};
});

View File

@@ -1,48 +1,51 @@
/* Copyright 2015-2019 Onestein (<https://www.onestein.eu>)
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('bi_view_editor.JoinNodeDialog', function (require) {
odoo.define("bi_view_editor.JoinNodeDialog", function(require) {
"use strict";
var Dialog = require("web.Dialog");
var core = require('web.core');
var core = require("web.core");
var qweb = core.qweb;
var _t = core._t;
var JoinNodeDialog = Dialog.extend({
xmlDependencies: Dialog.prototype.xmlDependencies.concat([
'/bi_view_editor/static/src/xml/bi_view_editor.xml',
"/bi_view_editor/static/src/xml/bi_view_editor.xml",
]),
events: {
"click li": "choiceClicked",
},
init: function (parent, options, choices, model_data) {
init: function(parent, options, choices, model_data) {
this.choices = choices;
// Prepare data for view
for (var i = 0; i < choices.length; i++) {
if (choices[i].join_node !== -1 && choices[i].table_alias !== -1) {
choices[i].model_name = model_data[choices[i].table_alias].model_name;
choices[i].model_name =
model_data[choices[i].table_alias].model_name;
}
choices[i].index = i;
}
var defaults = _.defaults(options || {}, {
title: _t("Join..."),
dialogClass: 'oe_act_window',
$content: qweb.render('bi_view_editor.JoinNodeDialog', {
'choices': choices,
dialogClass: "oe_act_window",
$content: qweb.render("bi_view_editor.JoinNodeDialog", {
choices: choices,
}),
buttons: [{
text: _t("Cancel"),
classes: "btn-default o_form_button_cancel",
close: true,
}],
buttons: [
{
text: _t("Cancel"),
classes: "btn-default o_form_button_cancel",
close: true,
},
],
});
this._super(parent, defaults);
},
choiceClicked: function (e) {
this.trigger('chosen', {
choice: this.choices[$(e.currentTarget).attr('data-index')],
choiceClicked: function(e) {
this.trigger("chosen", {
choice: this.choices[$(e.currentTarget).attr("data-index")],
});
this.close();
},

View File

@@ -1,87 +1,92 @@
/* Copyright 2015-2019 Onestein (<https://www.onestein.eu>)
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('bi_view_editor.ModelList', function (require) {
odoo.define("bi_view_editor.ModelList", function(require) {
"use strict";
var Widget = require('web.Widget');
var core = require('web.core');
var Widget = require("web.Widget");
var core = require("web.core");
var qweb = core.qweb;
var ModelList = Widget.extend({
template: 'bi_view_editor.ModelList',
template: "bi_view_editor.ModelList",
events: {
'keyup .search-bar > input': 'filterChanged',
"keyup .search-bar > input": "filterChanged",
},
init: function (parent) {
init: function(parent) {
var res = this._super(parent);
this.active_models = [];
this.cache_fields = {};
this.current_filter = '';
this.current_filter = "";
this.mode = null;
return res;
},
setMode: function (mode) {
if (mode === 'readonly') {
this.$el.find('.search-bar').attr('disabled', true);
this.$el.find('.class-list, .class').addClass('readonly');
setMode: function(mode) {
if (mode === "readonly") {
this.$el.find(".search-bar").attr("disabled", true);
this.$el.find(".class-list, .class").addClass("readonly");
} else {
this.$el.find('.search-bar').attr('disabled', false);
this.$el.find('.class-list, .class').removeClass('readonly');
this.$el.find(".search-bar").attr("disabled", false);
this.$el.find(".class-list, .class").removeClass("readonly");
}
this.mode = mode;
},
isActive: function (id) {
isActive: function(id) {
return this.active_models.indexOf(id) !== -1;
},
removeAsActive: function (id) {
removeAsActive: function(id) {
var i = this.active_models.indexOf(id);
this.active_models.splice(i, 1);
},
addAsActive: function (id) {
addAsActive: function(id) {
this.active_models.push(id);
},
loadModels: function (model_ids) {
loadModels: function(model_ids) {
return this._rpc({
model: 'ir.model',
method: 'get_models',
model: "ir.model",
method: "get_models",
args: model_ids ? [model_ids] : [],
});
},
loadFields: function (model_id) {
loadFields: function(model_id) {
if (!(model_id in this.cache_fields)) {
var deferred = this._rpc({
model: 'ir.model',
method: 'get_fields',
model: "ir.model",
method: "get_fields",
args: [model_id],
});
this.cache_fields[model_id] = deferred;
}
return this.cache_fields[model_id];
},
populateModels: function (models) {
populateModels: function(models) {
var self = this;
this.$el.find(".class-list").html('');
this.$el.find(".class-list").html("");
_.each(models, function (model) {
var $html = $(qweb.render('bi_view_editor.ModelListItem', {
'id': model.id,
'model': model.model,
'name': model.name,
}));
$html.find('.class').data('model', model).click(function () {
self.modelClicked($(this));
});
_.each(models, function(model) {
var $html = $(
qweb.render("bi_view_editor.ModelListItem", {
id: model.id,
model: model.model,
name: model.name,
})
);
$html
.find(".class")
.data("model", model)
.click(function() {
self.modelClicked($(this));
});
self.$el.find(".class-list").append($html);
if (self.isActive(model.id)) {
self.loadFields(model.id).done(function (fields) {
self.loadFields(model.id).done(function(fields) {
self.populateFields(fields, model.id);
});
}
});
},
populateFields: function (fields, model_id) {
populateFields: function(fields, model_id) {
var self = this;
if (!model_id && fields.length === 0) {
return;
@@ -91,59 +96,72 @@ odoo.define('bi_view_editor.ModelList', function (require) {
data_model_id = fields[0].model_id;
}
var $model_item = this.$el.find(".class[data-id='" + data_model_id + "']");
_.each(fields, function (field) {
var $field = $(qweb.render('bi_view_editor.ModelListFieldItem', {
name: field.name,
description: field.description,
})).data('field', field).click(function () {
self.fieldClicked($(this));
}).draggable({
'revert': 'invalid',
'scroll': false,
'helper': 'clone',
'appendTo': 'body',
'containment': 'window',
});
_.each(fields, function(field) {
var $field = $(
qweb.render("bi_view_editor.ModelListFieldItem", {
name: field.name,
description: field.description,
})
)
.data("field", field)
.click(function() {
self.fieldClicked($(this));
})
.draggable({
revert: "invalid",
scroll: false,
helper: "clone",
appendTo: "body",
containment: "window",
});
$model_item.after($field);
});
},
modelClicked: function ($el) {
if (this.mode === 'readonly') {
modelClicked: function($el) {
if (this.mode === "readonly") {
return;
}
var model = $el.data('model');
$el.parent().find('.field').remove();
var model = $el.data("model");
$el.parent()
.find(".field")
.remove();
if (this.isActive(model.id)) {
this.removeAsActive(model.id);
} else {
this.addAsActive(model.id);
this.loadFields(model.id).done(function (fields) {
this.populateFields(fields, model.id);
}.bind(this));
this.loadFields(model.id).done(
function(fields) {
this.populateFields(fields, model.id);
}.bind(this)
);
}
},
fieldClicked: function ($el) {
if (this.mode === 'readonly') {
fieldClicked: function($el) {
if (this.mode === "readonly") {
return;
}
this.trigger('field_clicked', $el.data('field'));
this.trigger("field_clicked", $el.data("field"));
},
filterChanged: function (e) {
filterChanged: function(e) {
var $input = $(e.target);
this.filter($input.val());
},
filter: function (value) {
filter: function(value) {
this.active_models = [];
this.$el.find('.field').remove();
var val = typeof value === 'undefined' ? this.current_filter : value.toLowerCase();
this.$el.find(".class").each(function () {
var data = $(this).data('model');
if (data.name.toLowerCase().indexOf(val) === -1 &&
data.model.toLowerCase().indexOf(val) === -1) {
$(this).addClass('d-none');
this.$el.find(".field").remove();
var val =
typeof value === "undefined"
? this.current_filter
: value.toLowerCase();
this.$el.find(".class").each(function() {
var data = $(this).data("model");
if (
data.name.toLowerCase().indexOf(val) === -1 &&
data.model.toLowerCase().indexOf(val) === -1
) {
$(this).addClass("d-none");
} else {
$(this).removeClass('d-none');
$(this).removeClass("d-none");
}
});
this.current_filter = val;
@@ -151,5 +169,4 @@ odoo.define('bi_view_editor.ModelList', function (require) {
});
return ModelList;
});

View File

@@ -1,48 +1,48 @@
/* Copyright 2015-2019 Onestein (<https://www.onestein.eu>)
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('bi_view_editor', function (require) {
odoo.define("bi_view_editor", function(require) {
"use strict";
var JoinNodeDialog = require('bi_view_editor.JoinNodeDialog');
var ModelList = require('bi_view_editor.ModelList');
var FieldList = require('bi_view_editor.FieldList').FieldList;
var JoinNodeDialog = require("bi_view_editor.JoinNodeDialog");
var ModelList = require("bi_view_editor.ModelList");
var FieldList = require("bi_view_editor.FieldList").FieldList;
var AbstractField = require('web.AbstractField');
var Data = require('web.data');
var field_registry = require('web.field_registry');
var AbstractField = require("web.AbstractField");
var Data = require("web.data");
var field_registry = require("web.field_registry");
var BiViewEditor = AbstractField.extend({
template: "bi_view_editor.Frame",
events: {
"click .clear-btn": "clear",
},
start: function () {
start: function() {
var self = this;
var res = this._super.apply(this, arguments);
// Init ModelList
this.model_list = new ModelList(this);
this.model_list.appendTo(this.$(".body > .left"));
this.model_list.on('field_clicked', this, function (field) {
this.model_list.on("field_clicked", this, function(field) {
self.addField(_.extend({}, field));
});
// Init FieldList
this.field_list = new FieldList(this);
this.field_list.appendTo(this.$(".body > .right"));
this.field_list.on('removed', this, this.fieldListRemoved);
this.field_list.on('updated', this, this.fieldListChanged);
this.field_list.on("removed", this, this.fieldListRemoved);
this.field_list.on("updated", this, this.fieldListChanged);
this.$el.find(".body > .right").droppable({
accept: "div.class-list div.field",
drop: function (event, ui) {
self.addField(_.extend({}, ui.draggable.data('field')));
ui.draggable.draggable('option', 'revert', false);
drop: function(event, ui) {
self.addField(_.extend({}, ui.draggable.data("field")));
ui.draggable.draggable("option", "revert", false);
},
});
this.on("change:effective_readonly", this, function () {
this.on("change:effective_readonly", this, function() {
this.updateMode();
});
this.renderValue();
@@ -50,61 +50,65 @@ odoo.define('bi_view_editor', function (require) {
this.updateMode();
return res;
},
clear: function () {
if (this.mode !== 'readonly') {
clear: function() {
if (this.mode !== "readonly") {
this.field_list.set([]);
this.loadAndPopulateModelList();
this._setValue(this.field_list.get());
}
},
fieldListChanged: function () {
fieldListChanged: function() {
this._setValue(this.field_list.get());
},
fieldListRemoved: function () {
fieldListRemoved: function() {
console.log(this.field_list.get());
this._setValue(this.field_list.get());
var model = new Data.DataSet(this, "bve.view");
model.call('get_clean_list', [this.value]).then(function (result) {
this.field_list.set(JSON.parse(result));
this._setValue(this.field_list.get());
}.bind(this));
model.call("get_clean_list", [this.value]).then(
function(result) {
this.field_list.set(JSON.parse(result));
this._setValue(this.field_list.get());
}.bind(this)
);
this.loadAndPopulateModelList();
},
renderValue: function () {
renderValue: function() {
this.field_list.set(JSON.parse(this.value));
},
updateMode: function () {
if (this.mode === 'readonly') {
this.$el.find('.clear-btn').addClass('d-none');
updateMode: function() {
if (this.mode === "readonly") {
this.$el.find(".clear-btn").addClass("d-none");
this.$el.find(".body .right").droppable("option", "disabled", true);
} else {
this.$el.find('.clear-btn').removeClass('d-none');
this.$el.find('.body .right').droppable('option', 'disabled', false);
this.$el.find(".clear-btn").removeClass("d-none");
this.$el.find(".body .right").droppable("option", "disabled", false);
}
this.field_list.setMode(this.mode);
this.model_list.setMode(this.mode);
},
loadAndPopulateModelList: function () {
loadAndPopulateModelList: function() {
var model_ids = null;
if (this.field_list.get().length > 0) {
model_ids = this.field_list.getModelIds();
}
this.model_list.loadModels(model_ids).done(function (models) {
this.model_list.populateModels(models);
}.bind(this));
this.model_list.loadModels(model_ids).done(
function(models) {
this.model_list.populateModels(models);
}.bind(this)
);
},
getTableAlias: function (field) {
if (typeof field.table_alias === 'undefined') {
getTableAlias: function(field) {
if (typeof field.table_alias === "undefined") {
var model_ids = this.field_list.getModelIds();
var n = 1;
while (typeof model_ids["t" + n] !== 'undefined') {
while (typeof model_ids["t" + n] !== "undefined") {
n++;
}
return "t" + n;
}
return field.table_alias;
},
addFieldAndJoinNode: function (field, join_node) {
addFieldAndJoinNode: function(field, join_node) {
if (join_node.join_node === -1 || join_node.table_alias === -1) {
field.table_alias = this.getTableAlias(field);
if (join_node.join_node === -1) {
@@ -121,31 +125,37 @@ odoo.define('bi_view_editor', function (require) {
this.loadAndPopulateModelList();
this._setValue(this.field_list.get());
},
addField: function (field) {
addField: function(field) {
var data = _.extend({}, field);
var model = new Data.DataSet(this, "ir.model");
var field_data = this.field_list.get();
model.call('get_join_nodes', [field_data, data]).then(function (result) {
if (result.length === 1) {
this.addFieldAndJoinNode(data, result[0]);
} else if (result.length > 1) {
var dialog = new JoinNodeDialog(this, {}, result, this.field_list.getModelData());
dialog.open().on('chosen', this, function (e) {
this.addFieldAndJoinNode(data, e.choice);
});
} else {
data.table_alias = this.getTableAlias(data);
this.field_list.add(data);
this.loadAndPopulateModelList();
this._setValue(this.field_list.get());
}
}.bind(this));
model.call("get_join_nodes", [field_data, data]).then(
function(result) {
if (result.length === 1) {
this.addFieldAndJoinNode(data, result[0]);
} else if (result.length > 1) {
var dialog = new JoinNodeDialog(
this,
{},
result,
this.field_list.getModelData()
);
dialog.open().on("chosen", this, function(e) {
this.addFieldAndJoinNode(data, e.choice);
});
} else {
data.table_alias = this.getTableAlias(data);
this.field_list.add(data);
this.loadAndPopulateModelList();
this._setValue(this.field_list.get());
}
}.bind(this)
);
},
_parseValue: function (value) {
_parseValue: function(value) {
return JSON.stringify(value);
},
});
field_registry.add('BVEEditor', BiViewEditor);
field_registry.add("BVEEditor", BiViewEditor);
});

View File

@@ -1,81 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<template>
<t t-name="bi_view_editor.Frame">
<div class="oe_form_field_bi_editor">
<div class="body">
<div class="left">
</div>
<div class="right">
</div>
<div class="clear"></div>
<div class="clear" />
</div>
<div class="footer">
<div class="left"></div>
<div class="right"><button class="clear-btn d-none"><span class="fa fa-eraser"></span> Clear</button></div>
<div class="left" />
<div class="right">
<button class="clear-btn d-none"><span
class="fa fa-eraser"
/> Clear</button>
</div>
</div>
</div>
</t>
<!-- Join Node Dialog -->
<t t-name="bi_view_editor.JoinNodeDialog">
<div class="oe_bi_view_editor_join_node_dialog">
<ul class="list-group" >
<ul class="list-group">
<t t-foreach="choices" t-as="choice">
<t t-if="choice.join_node !== -1 and choice.table_alias !== -1">
<li class="list-group-item list-group-item-action text-primary" t-attf-data-index="#{choice.index}">
<li
class="list-group-item list-group-item-action text-primary"
t-attf-data-index="#{choice.index}"
>
<b>Use the existing node</b>
</li>
</t>
<t t-elif="choice.join_node !== -1">
<li class="list-group-item list-group-item-action text-success" t-attf-data-index="#{choice.index}">
<li
class="list-group-item list-group-item-action text-success"
t-attf-data-index="#{choice.index}"
>
Use the field
<b><t t-esc="choice.model_name"/></b>
<i class="fa fa-caret-right"/>
<b><t t-esc="choice.description"/></b>
<b>
<t t-esc="choice.model_name" />
</b>
<i class="fa fa-caret-right" />
<b>
<t t-esc="choice.description" />
</b>
<span class="badge">new</span>
</li>
</t>
<t t-else="">
<li class="list-group-item list-group-item-action" t-attf-data-index="#{choice.index}">
<li
class="list-group-item list-group-item-action"
t-attf-data-index="#{choice.index}"
>
Use the field
<b><t t-esc="choice.model_name"/></b>
<i class="fa fa-caret-right"/>
<b><t t-esc="choice.description"/></b>
<b>
<t t-esc="choice.model_name" />
</b>
<i class="fa fa-caret-right" />
<b>
<t t-esc="choice.description" />
</b>
</li>
</t>
</t>
</ul>
</div>
</t>
<!-- ModelList -->
<t t-name="bi_view_editor.ModelList">
<div>
<div class="search-bar">
<span class="fa fa-search"></span>
<span class="fa fa-search" />
<input type="text" class="search-bar" />
</div>
<div class="class-list">
</div>
</div>
</t>
<!-- ModelListItem -->
<t t-name="bi_view_editor.ModelListItem">
<div class="class-container">
<div class="class" t-attf-title="#{model}" t-attf-data-id="#{id}"><t t-esc="name"/></div>
<div class="class" t-attf-title="#{model}" t-attf-data-id="#{id}">
<t t-esc="name" />
</div>
</div>
</t>
<!-- ModelListFieldItem-->
<t t-name="bi_view_editor.ModelListFieldItem">
<div class="field" t-attf-title="#{name}" t-attf-data-id="#{name}"><t t-esc="description"/></div>
<div class="field" t-attf-title="#{name}" t-attf-data-id="#{name}">
<t t-esc="description" />
</div>
</t>
<!-- FieldList -->
<t t-name="bi_view_editor.FieldList">
<div>
@@ -85,7 +102,7 @@
<th>Name</th>
<th>Model</th>
<th>Options</th>
<th></th>
<th />
</tr>
</thead>
<tbody>
@@ -93,90 +110,150 @@
</table>
</div>
</t>
<!-- FieldContextMenu -->
<t t-name="bi_view_editor.FieldList.FieldContextMenu">
<ul class="context-menu d-none">
<li>
<div class="checkbox">
<label>
<input type="checkbox" data-for="column" class="checkbox-column"/> Column
<label>
<input
type="checkbox"
data-for="column"
class="checkbox-column"
/> Column
</label>
</div>
</li>
<li>
<div class="checkbox">
<label>
<input type="checkbox" data-for="row" class="checkbox-row"/> Row
<input
type="checkbox"
data-for="row"
class="checkbox-row"
/> Row
</label>
</div>
</li>
<li>
<div class="checkbox">
<label>
<input type="checkbox" data-for="measure" class="checkbox-measure"/> Measure
<input
type="checkbox"
data-for="measure"
class="checkbox-measure"
/> Measure
</label>
</div>
</li>
<li>
<div class="checkbox">
<label>
<input type="checkbox" data-for="list" class="checkbox-list"/> List
<input
type="checkbox"
data-for="list"
class="checkbox-list"
/> List
</label>
</div>
</li>
</ul>
</t>
<!-- JoinContextMenu -->
<t t-name="bi_view_editor.FieldList.JoinContextMenu">
<ul class="context-menu d-none">
<li>
<div class="checkbox">
<label>
<input type="checkbox" data-for="join_left" class="checkbox-join-left"/> Join Left
<input
type="checkbox"
data-for="join_left"
class="checkbox-join-left"
/> Join Left
</label>
</div>
</li>
</ul>
</t>
<!-- FieldListItem -->
<t t-name="bi_view_editor.FieldListItem">
<tr t-attf-data-id="#{field._id}" class="field-node">
<td>
<input t-attf-data-id="#{field._id}" t-attf-title="#{field.model_name} (#{field.model})" class="form-control input-sm" type="text" name="description" t-attf-value="#{field.description}"/>
<input
t-attf-data-id="#{field._id}"
t-attf-title="#{field.model_name} (#{field.model})"
class="form-control input-sm"
type="text"
name="description"
t-attf-value="#{field.description}"
/>
</td>
<td>
<t t-esc="field.model_name" />
</td>
<td>
<span data-for="column" t-attf-class="#{field.column and 'fa fa-columns' or 'fa fa-columns d-none'}" title='Column'></span>
<span data-for="row" t-attf-class="#{field.row and 'fa fa-bars' or 'fa fa-bars d-none'}" title='Row'></span>
<span data-for="measure" t-attf-class="#{field.measure and 'fa fa-bar-chart-o' or 'fa fa-bar-chart-o d-none'}" title='Measure'></span>
<span data-for="list" t-attf-class="#{field.list and 'fa fa-list' or 'fa fa-list d-none'}" title='List'></span>
<span
data-for="column"
t-attf-class="#{field.column and 'fa fa-columns' or 'fa fa-columns d-none'}"
title='Column'
/>
<span
data-for="row"
t-attf-class="#{field.row and 'fa fa-bars' or 'fa fa-bars d-none'}"
title='Row'
/>
<span
data-for="measure"
t-attf-class="#{field.measure and 'fa fa-bar-chart-o' or 'fa fa-bar-chart-o d-none'}"
title='Measure'
/>
<span
data-for="list"
t-attf-class="#{field.list and 'fa fa-list' or 'fa fa-list d-none'}"
title='List'
/>
</td>
<td>
<span t-attf-data-id="#{field._id}" class="delete-button fa fa-trash-o"/>
<span
t-attf-data-id="#{field._id}"
class="delete-button fa fa-trash-o"
/>
</td>
</tr>
</t>
<t t-name="bi_view_editor.JoinListItem">
<tr t-attf-data-id="#{field._id}" class="join-node">
<td colspan="4">
<input class="d-none" type="text" name="description" t-attf-value="#{field.description}"/>
<input
class="d-none"
type="text"
name="description"
t-attf-value="#{field.description}"
/>
<t t-if="field.join_node > field.table_alias">
<b><t t-esc="field.model_name" /></b>
<i class="fa fa-caret-right"/>
<small><t t-esc="field.description" /></small>
<b>
<t t-esc="field.model_name" />
</b>
<i class="fa fa-caret-right" />
<small>
<t t-esc="field.description" />
</small>
</t>
<t t-else="">
<small><t t-esc="field.description" /></small>
<i class="fa fa-caret-left"/>
<b><t t-esc="field.model_name" /></b>
<small>
<t t-esc="field.description" />
</small>
<i class="fa fa-caret-left" />
<b>
<t t-esc="field.model_name" />
</b>
</t>
<span t-attf-class="#{!field.join_left and 'd-none' or ''}" data-for="join_left"><i>(join left)</i></span>
<span
t-attf-class="#{!field.join_left and 'd-none' or ''}"
data-for="join_left"
>
<i>(join left)</i>
</span>
</td>
</tr>
</t>