odoo/addons/web_diagram/static/src/js/diagram.js

308 lines
10 KiB
JavaScript

/*---------------------------------------------------------
* OpenERP diagram library
*---------------------------------------------------------*/
openerp.web_diagram = function (openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t,
_lt = openerp.web._lt;
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
openerp.web.DiagramView = openerp.web.View.extend({
display_name: _lt('Diagram'),
searchable: false,
init: function(parent, dataset, view_id, options) {
this._super(parent);
this.set_default_options(options);
this.view_manager = parent;
this.dataset = dataset;
this.model = this.dataset.model;
this.view_id = view_id;
this.domain = this.dataset._domain || [];
this.context = {};
this.ids = this.dataset.ids;
},
start: function() {
this._super();
return this.rpc("/web_diagram/diagram/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded);
},
toTitleCase: function(str) {
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
},
on_loaded: function(result) {
var self = this;
if(this.ids && this.ids.length) {
this.id = this.ids[self.dataset.index || 0];
}
this.fields_view = result.fields_view,
this.view_id = this.fields_view.view_id,
this.fields = this.fields_view.fields,
this.nodes = this.fields_view.arch.children[0],
this.connectors = this.fields_view.arch.children[1],
this.node = this.nodes.attrs.object,
this.connector = this.connectors.attrs.object;
this.$element.html(QWeb.render("DiagramView", this));
this.$element.find('div.oe_diagram_pager button[data-pager-action]').click(function() {
var action = $(this).data('pager-action');
self.on_pager_action(action);
});
this.do_update_pager();
// New Node,Edge
this.$element.find('#new_node.oe_diagram_button_new').click(function(){self.add_edit_node(null, self.node);});
if(this.id) {
self.get_diagram_info();
}
},
get_diagram_info: function() {
var self = this;
var params = {
'id': this.id,
'model': this.model,
'node': this.node,
'connector': this.connector,
'bgcolor': this.nodes.attrs.bgcolor,
'shape': this.nodes.attrs.shape,
'src_node': this.connectors.attrs.source,
'des_node': this.connectors.attrs.destination,
'visible_nodes': [],
'invisible_nodes': [],
'node_fields': [],
'connectors': [],
'connectors_fields': []
};
_.each(this.nodes.children, function(child) {
if(child.attrs.invisible == '1')
params['invisible_nodes'].push(child.attrs.name);
else {
params['visible_nodes'].push(child.attrs.name);
params['node_fields'].push(self.fields[child.attrs.name]['string']|| this.toTitleCase(child.attrs.name));
}
});
_.each(this.connectors.children, function(conn) {
params['connectors_fields'].push(self.fields[conn.attrs.name]['string']|| this.toTitleCase(conn.attrs.name));
params['connectors'].push(conn.attrs.name);
});
this.rpc(
'/web_diagram/diagram/get_diagram_info',params,
function(result) {
self.draw_diagram(result);
}
);
},
on_diagram_loaded: function(record) {
var id_record = record['id'];
if(id_record) {
this.id = id_record;
this.get_diagram_info();
}
},
select_node: function (node, element) {
if (!this.selected_node) {
this.selected_node = node;
element.attr('stroke', 'red');
return;
}
// Re-click selected node, deselect it
if (node.id === this.selected_node.id) {
this.selected_node = null;
element.attr('stroke', 'black');
return;
}
this.add_edit_node(null, this.connector, {
act_from: this.selected_node.id,
act_to: node.id
});
},
draw_diagram: function(result) {
this.selected_node = null;
var diagram = new Graph();
this.active_model = result['id_model'];
var res_nodes = result['nodes'];
var res_connectors = result['conn'];
//Custom logic
var self = this;
var renderer = function(r, n) {
var shape = (n.node.shape === 'rectangle') ? 'rect' : 'ellipse';
var node = r[shape](n.node.x, n.node.y).attr({
"fill": n.node.color
});
var nodes = r.set(node, r.text(n.node.x, n.node.y, (n.label || n.id)))
.attr("cursor", "pointer")
.dblclick(function() {
self.add_edit_node(n.node.id, self.node);
})
.mousedown(function () { node.moved = false; })
.mousemove(function () { node.moved = true; })
.click(function () {
// Ignore click from move event
if (node.moved) { return; }
self.select_node(n.node, node);
});
if (shape === 'rect') {
node.attr({width: "60", height: "44"});
node.next.attr({"text-anchor": "middle", x: n.node.x + 20, y: n.node.y + 20});
} else {
node.attr({rx: "40", ry: "20"});
}
return nodes;
};
_.each(res_nodes, function(res_node) {
diagram.addNode(res_node['name'],{node: res_node,render: renderer});
});
// Id for Path(Edges)
var edge_ids = [];
_.each(res_connectors, function(connector, index) {
edge_ids.push(index);
diagram.addEdge(connector['source'], connector['destination'], {directed : true, label: connector['signal']});
});
self.$element.find('.diagram').empty();
var layouter = new Graph.Layout.Ordered(diagram);
var render_diagram = new Graph.Renderer.Raphael('dia-canvas', diagram, $('div#dia-canvas').width(), $('div#dia-canvas').height());
_.each(diagram.edges, function(edge, index) {
if(edge.connection) {
edge.connection.fg.attr({cursor: "pointer"}).dblclick(function() {
self.add_edit_node(edge_ids[index], self.connector);
});
}
});
},
add_edit_node: function(id, model, defaults) {
defaults = defaults || {};
var self = this;
if(!model)
model = self.node;
if(id)
id = parseInt(id, 10);
var action_manager = new openerp.web.ActionManager(this);
var dialog = new openerp.web.Dialog(this, {
width: 800,
height: 600,
buttons : [
{text: _t("Cancel"), click: function() { $(this).dialog('destroy'); }},
{text: _t("Save"), click: function() {
var form_view = action_manager.inner_viewmanager.views.form.controller;
form_view.do_save(function() {
self.dataset.read_index(_.keys(self.fields_view.fields), self.on_diagram_loaded);
});
$(this).dialog('destroy');
}
}
]
}).start().open();
action_manager.appendTo(dialog.$element);
action_manager.do_action({
res_model : model,
res_id: id,
views : [[false, 'form']],
type : 'ir.actions.act_window',
flags : {
search_view: false,
sidebar : false,
views_switcher : false,
action_buttons : false,
pager: false
}
});
var form_controller = action_manager.inner_viewmanager.views.form.controller;
var form_fields;
if(model == self.node) {
form_fields = ['wkf_id'];
} else {
form_fields = ['act_from', 'act_to'];
}
if(model == self.node || id) {
$.each(form_fields, function(index, fld) {
form_controller.on_record_loaded.add_first(function() {
form_controller.fields[fld].modifiers.readonly = true;
form_controller.fields[fld].$input.attr('disabled', true);
form_controller.fields[fld].$drop_down.unbind();
form_controller.fields[fld].$menu_btn.unbind();
});
});
}
if(!id && (model == self.node)) {
$.each(form_fields, function(index, fld) {
form_controller.on_record_loaded.add_last(function() {
form_controller.fields[fld].set_value([self.id,self.active_model]);
form_controller.fields[fld].dirty = true;
});
});
}
if (!_.isEmpty(defaults)) {
form_controller.on_record_loaded.add_last(function () {
_(form_fields).each(function (field) {
if (!defaults[field]) { return; }
form_controller.fields[field].set_value(defaults[field]);
form_controller.fields[field].dirty = true;
});
});
}
},
on_pager_action: function(action) {
switch (action) {
case 'first':
this.dataset.index = 0;
break;
case 'previous':
this.dataset.previous();
break;
case 'next':
this.dataset.next();
break;
case 'last':
this.dataset.index = this.dataset.ids.length - 1;
break;
}
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_diagram_loaded);
this.do_update_pager();
},
do_update_pager: function(hide_index) {
var $pager = this.$element.find('div.oe_diagram_pager');
var index = hide_index ? '-' : this.dataset.index + 1;
if(!this.dataset.count) {
this.dataset.count = this.dataset.ids.length;
}
$pager.find('span.oe_pager_index').html(index);
$pager.find('span.oe_pager_count').html(this.dataset.count);
}
});
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: