Browse Source

pre-commit

myc-14.0-py3o
Andrea 4 years ago
parent
commit
57aee07bc0
  1. 6
      bi_view_editor/models/bve_view.py
  2. 12
      bi_view_editor/models/bve_view_line.py
  3. 19
      bi_view_editor/models/ir_model.py
  4. 6
      bi_view_editor/security/rules.xml
  5. 60
      bi_view_editor/static/src/js/bi_view_editor.FieldList.js
  6. 6
      bi_view_editor/static/src/js/bi_view_editor.JoinNodeDialog.js
  7. 46
      bi_view_editor/static/src/js/bi_view_editor.ModelList.js
  8. 40
      bi_view_editor/static/src/js/bi_view_editor.js
  9. 13
      bi_view_editor/static/src/xml/bi_view_editor.xml

6
bi_view_editor/models/bve_view.py

@ -320,7 +320,11 @@ class BveView(models.Model):
try:
with self.env.cr.savepoint():
self.env.cr.execute(
"CREATE or REPLACE VIEW %s as (%s)", (AsIs(view_name), AsIs(query),)
"CREATE or REPLACE VIEW %s as (%s)",
(
AsIs(view_name),
AsIs(query),
),
)
except Exception as e:
raise UserError(

12
bi_view_editor/models/bve_view_line.py

@ -57,8 +57,16 @@ class BveViewLine(models.Model):
def _constrains_unique_fields_check(self):
seen = set()
for line in self.mapped("bve_view_id.field_ids"):
if (line.table_alias, line.field_id.id,) not in seen:
seen.add((line.table_alias, line.field_id.id,))
if (
line.table_alias,
line.field_id.id,
) not in seen:
seen.add(
(
line.table_alias,
line.field_id.id,
)
)
else:
raise ValidationError(
_("Field %s/%s is duplicated.\n" "Please remove the duplications.")

19
bi_view_editor/models/ir_model.py

@ -85,7 +85,11 @@ class IrModel(models.Model):
for field in fields:
for table_alias in model_table_map[field.model_id.id]:
model_list.append(
dict(dict_for_field(field), table_alias=table_alias, join_node=-1,)
dict(
dict_for_field(field),
table_alias=table_alias,
join_node=-1,
)
)
return model_list
@ -125,16 +129,15 @@ class IrModel(models.Model):
@api.model
def get_related_models(self, model_table_map):
""" Return list of model dicts for all models that can be
joined with the already selected models.
"""Return list of model dicts for all models that can be
joined with the already selected models.
"""
domain = self._get_related_models_domain(model_table_map)
return self.sudo().search(domain, order="name asc")
@api.model
def get_models(self, table_model_map=None):
""" Return list of model dicts for all available models.
"""
"""Return list of model dicts for all available models."""
self = self.with_context(lang=self.env.user.lang)
model_table_map = defaultdict(list)
for k, v in (table_model_map or {}).items():
@ -150,10 +153,10 @@ class IrModel(models.Model):
@api.model
def get_join_nodes(self, field_data, new_field):
""" Return list of field dicts of join nodes
"""Return list of field dicts of join nodes
Return all possible join nodes to add new_field to the query
containing model_ids.
Return all possible join nodes to add new_field to the query
containing model_ids.
"""
def remove_duplicate_nodes(join_nodes):

6
bi_view_editor/security/rules.xml

@ -4,8 +4,8 @@
<field name="name">bve_view read access</field>
<field name="model_id" search="[('model','=','bve.view')]" model="ir.model" />
<field name="global" eval="True" />
<field
name="domain_force"
> ['|',('user_ids','=',False),('user_ids','in',user.id)]</field>
<field name="domain_force">
['|',('user_ids','=',False),('user_ids','in',user.id)]
</field>
</record>
</odoo>

60
bi_view_editor/static/src/js/bi_view_editor.FieldList.js

@ -1,7 +1,7 @@
/* 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");
@ -11,14 +11,14 @@ odoo.define("bi_view_editor.FieldList", function(require) {
var FieldListContextMenu = Widget.extend(
_.extend({}, mixins.EventDispatcherMixin, {
start: function() {
start: function () {
var res = this._super.apply(this, arguments);
this.$el.mouseleave(function() {
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",
@ -31,7 +31,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
var FieldListFieldContextMenu = FieldListContextMenu.extend({
template: "bi_view_editor.FieldList.FieldContextMenu",
open: function(x, y, $item) {
open: function (x, y, $item) {
var field = $item.data("field");
this.$el.find(".checkbox-column").prop("checked", field.column);
this.$el.find(".checkbox-row").prop("checked", field.row);
@ -49,7 +49,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
var events = this._super(x, y, field);
this.$el.find("input").unbind("change");
this.$el.find("input").change(function() {
this.$el.find("input").change(function () {
var $checkbox = $(this);
var property = $checkbox.attr("data-for");
field[property] = $checkbox.is(":checked");
@ -62,13 +62,13 @@ odoo.define("bi_view_editor.FieldList", function(require) {
var FieldListJoinContextMenu = FieldListContextMenu.extend({
template: "bi_view_editor.FieldList.JoinContextMenu",
open: function(x, y, $item) {
open: function (x, y, $item) {
var node = $item.data("field");
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").change(function () {
var $checkbox = $(this);
var property = $checkbox.attr("data-for");
node[property] = $checkbox.is(":checked");
@ -84,14 +84,14 @@ odoo.define("bi_view_editor.FieldList", function(require) {
"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.on(
"change",
this,
function(f, $item) {
function (f, $item) {
$item.data("field", f);
this.refreshItem($item);
this.trigger("updated");
@ -102,7 +102,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
this.contextmenu_join.on(
"change",
this,
function(f, $item) {
function (f, $item) {
$item.data("field", f);
this.refreshItem($item);
this.trigger("updated");
@ -112,7 +112,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
this.mode = null;
return res;
},
setMode: function(mode) {
setMode: function (mode) {
if (mode === "readonly") {
this.$el.find('input[type="text"]').attr("disabled", true);
this.$el.find(".delete-button").addClass("d-none");
@ -122,28 +122,26 @@ odoo.define("bi_view_editor.FieldList", function(require) {
}
this.mode = mode;
},
get: function() {
get: function () {
return $.makeArray(
this.$el.find("tbody tr").map(function() {
this.$el.find("tbody tr").map(function () {
var field = $(this).data("field");
field.description = $(this)
.find('input[name="description"]')
.val();
field.description = $(this).find('input[name="description"]').val();
return field;
})
);
},
getModelIds: function() {
getModelIds: function () {
var model_ids = {};
this.$el.find("tbody tr").each(function() {
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() {
this.$el.find("tbody tr").each(function () {
var data = $(this).data("field");
model_data[data.table_alias] = {
model_id: data.model_id,
@ -152,7 +150,7 @@ 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;
@ -169,7 +167,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
var i = 0;
var name = field.name;
while (
this.get().filter(function(item) {
this.get().filter(function (item) {
return item.name === field.name;
}).length > 0
) {
@ -189,7 +187,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
)
)
.data("field", field)
.contextmenu(function(e) {
.contextmenu(function (e) {
var $item = $(this);
if (self.mode === "readonly") {
return;
@ -200,12 +198,12 @@ odoo.define("bi_view_editor.FieldList", function(require) {
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);
},
set: function(fields) {
set: function (fields) {
var set_fields = fields;
if (!set_fields) {
set_fields = [];
@ -215,7 +213,7 @@ odoo.define("bi_view_editor.FieldList", function(require) {
this.add(set_fields[i]);
}
},
openContextMenu: function($item, x, y) {
openContextMenu: function ($item, x, y) {
var field = $item.data("field");
var contextmenu = field.join_node
? this.contextmenu_join
@ -226,10 +224,10 @@ odoo.define("bi_view_editor.FieldList", function(require) {
}
contextmenu.open(x - 20, y - 20, $item);
},
refreshItem: function($item) {
refreshItem: function ($item) {
var data = $item.data("field");
var $attributes = $item.find("span[data-for], img[data-for]");
$.each($attributes, function() {
$.each($attributes, function () {
var $attribute = $(this);
var value = data[$attribute.attr("data-for")];
if (value) {
@ -239,12 +237,12 @@ odoo.define("bi_view_editor.FieldList", function(require) {
}
});
},
removeClicked: function(e) {
removeClicked: function (e) {
var $button = $(e.currentTarget);
var id = $button.attr("data-id");
this.remove(id);
},
keyupDescription: function() {
keyupDescription: function () {
this.trigger("updated");
},
});

6
bi_view_editor/static/src/js/bi_view_editor.JoinNodeDialog.js

@ -1,7 +1,7 @@
/* 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");
@ -16,7 +16,7 @@ odoo.define("bi_view_editor.JoinNodeDialog", function(require) {
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++) {
@ -43,7 +43,7 @@ odoo.define("bi_view_editor.JoinNodeDialog", function(require) {
});
this._super(parent, defaults);
},
choiceClicked: function(e) {
choiceClicked: function (e) {
this.trigger("chosen", {
choice: this.choices[$(e.currentTarget).attr("data-index")],
});

46
bi_view_editor/static/src/js/bi_view_editor.ModelList.js

@ -1,7 +1,7 @@
/* 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");
@ -13,7 +13,7 @@ odoo.define("bi_view_editor.ModelList", function(require) {
events: {
"keyup .search-bar > input": "filterChanged",
},
init: function(parent) {
init: function (parent) {
var res = this._super(parent);
this.active_models = [];
this.cache_fields = {};
@ -21,7 +21,7 @@ odoo.define("bi_view_editor.ModelList", function(require) {
this.mode = null;
return res;
},
setMode: function(mode) {
setMode: function (mode) {
if (mode === "readonly") {
this.$el.find(".search-bar").attr("disabled", true);
this.$el.find(".class-list, .class").addClass("readonly");
@ -31,24 +31,24 @@ odoo.define("bi_view_editor.ModelList", function(require) {
}
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",
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",
@ -59,11 +59,11 @@ odoo.define("bi_view_editor.ModelList", function(require) {
}
return this.cache_fields[model_id];
},
populateModels: function(models) {
populateModels: function (models) {
var self = this;
this.$el.find(".class-list").html("");
_.each(models, function(model) {
_.each(models, function (model) {
var $html = $(
qweb.render("bi_view_editor.ModelListItem", {
id: model.id,
@ -74,19 +74,19 @@ odoo.define("bi_view_editor.ModelList", function(require) {
$html
.find(".class")
.data("model", model)
.click(function() {
.click(function () {
self.modelClicked($(this));
});
self.$el.find(".class-list").append($html);
if (self.isActive(model.id)) {
self.loadFields(model.id).then(function(fields) {
self.loadFields(model.id).then(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;
@ -96,7 +96,7 @@ 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) {
_.each(fields, function (field) {
var $field = $(
qweb.render("bi_view_editor.ModelListFieldItem", {
name: field.name,
@ -104,7 +104,7 @@ odoo.define("bi_view_editor.ModelList", function(require) {
})
)
.data("field", field)
.click(function() {
.click(function () {
self.fieldClicked($(this));
})
.draggable({
@ -117,43 +117,41 @@ odoo.define("bi_view_editor.ModelList", function(require) {
$model_item.after($field);
});
},
modelClicked: function($el) {
modelClicked: function ($el) {
if (this.mode === "readonly") {
return;
}
var model = $el.data("model");
$el.parent()
.find(".field")
.remove();
$el.parent().find(".field").remove();
if (this.isActive(model.id)) {
this.removeAsActive(model.id);
} else {
this.addAsActive(model.id);
this.loadFields(model.id).then(
function(fields) {
function (fields) {
this.populateFields(fields, model.id);
}.bind(this)
);
}
},
fieldClicked: function($el) {
fieldClicked: function ($el) {
if (this.mode === "readonly") {
return;
}
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() {
this.$el.find(".class").each(function () {
var data = $(this).data("model");
if (
data.name.toLowerCase().indexOf(val) === -1 &&

40
bi_view_editor/static/src/js/bi_view_editor.js

@ -1,7 +1,7 @@
/* 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");
@ -17,32 +17,32 @@ odoo.define("bi_view_editor", function(require) {
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")).then(
function() {
function () {
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) {
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();
@ -53,31 +53,31 @@ odoo.define("bi_view_editor", function(require) {
return res;
},
clear: function() {
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 () {
this._setValue(this.field_list.get());
var model = new Data.DataSet(this, "bve.view");
model.call("get_clean_list", [this.lastSetValue]).then(
function(result) {
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() {
updateMode: function () {
if (this.mode === "readonly") {
this.$el.find(".clear-btn").addClass("d-none");
this.$el.find(".body .right").droppable("option", "disabled", true);
@ -88,18 +88,18 @@ odoo.define("bi_view_editor", function(require) {
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).then(
function(models) {
function (models) {
this.model_list.populateModels(models);
}.bind(this)
);
},
getTableAlias: function(field) {
getTableAlias: function (field) {
if (typeof field.table_alias === "undefined") {
var model_ids = this.field_list.getModelIds();
var n = 1;
@ -110,7 +110,7 @@ odoo.define("bi_view_editor", function(require) {
}
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) {
@ -127,12 +127,12 @@ 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) {
function (result) {
if (result.length === 1) {
this.addFieldAndJoinNode(data, result[0]);
} else if (result.length > 1) {
@ -142,7 +142,7 @@ odoo.define("bi_view_editor", function(require) {
result,
this.field_list.getModelData()
);
dialog.open().on("chosen", this, function(e) {
dialog.open().on("chosen", this, function (e) {
this.addFieldAndJoinNode(data, e.choice);
});
} else {
@ -154,7 +154,7 @@ odoo.define("bi_view_editor", function(require) {
}.bind(this)
);
},
_parseValue: function(value) {
_parseValue: function (value) {
return JSON.stringify(value);
},
});

13
bi_view_editor/static/src/xml/bi_view_editor.xml

@ -4,6 +4,7 @@
<div class="oe_form_field_bi_editor">
<div class="body">
<div class="left">
</div>
<div class="right">
@ -13,9 +14,10 @@
<div class="footer">
<div class="left" />
<div class="right">
<button class="clear-btn d-none"><span
class="fa fa-eraser"
/> Clear</button>
<button class="clear-btn d-none">
<span class="fa fa-eraser" />
Clear
</button>
</div>
</div>
</div>
@ -76,6 +78,7 @@
<input type="text" class="search-bar" />
</div>
<div class="class-list">
</div>
</div>
</t>
@ -106,6 +109,7 @@
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
@ -165,7 +169,8 @@
type="checkbox"
data-for="join_left"
class="checkbox-join-left"
/> Join Left
/>
Join Left
</label>
</div>
</li>

Loading…
Cancel
Save