[MERGE] diagram view
bzr revid: xmo@openerp.com-20110906082222-r0e0glqmr0hlub55
This commit is contained in:
commit
38960ee912
|
@ -1,6 +1,16 @@
|
||||||
{
|
{
|
||||||
"name" : "OpenERP Web Diagram",
|
"name" : "OpenERP Web Diagram",
|
||||||
"version" : "2.0",
|
"version" : "2.0",
|
||||||
"depends" : [],
|
"depends" : ["base"],
|
||||||
'active': False,
|
"js": [
|
||||||
|
'static/lib/js/raphael-min.js',
|
||||||
|
'static/lib/js/dracula_graffle.js',
|
||||||
|
'static/lib/js/dracula_graph.js',
|
||||||
|
'static/lib/js/dracula_algorithms.js',
|
||||||
|
'static/src/js/diagram.js'
|
||||||
|
],
|
||||||
|
'css' : [
|
||||||
|
"static/src/css/base_diagram.css",
|
||||||
|
],
|
||||||
|
'active': True,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,57 +6,47 @@ class DiagramView(View):
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def load(self, req, model, view_id):
|
def load(self, req, model, view_id):
|
||||||
print req
|
|
||||||
print dir(req)
|
|
||||||
fields_view = self.fields_view_get(req, model, view_id, 'diagram')
|
fields_view = self.fields_view_get(req, model, view_id, 'diagram')
|
||||||
return {'fields_view': fields_view}
|
return {'fields_view': fields_view}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def get_diagram_info(self, req, **kw):
|
def get_diagram_info(self, req, id, model, node, connector, src_node, des_node, **kw):
|
||||||
id = kw['id']
|
|
||||||
model = kw['model']
|
|
||||||
node = kw['node']
|
|
||||||
connector = kw['connector']
|
|
||||||
src_node = kw['src_node']
|
|
||||||
des_node = kw['des_node']
|
|
||||||
|
|
||||||
visible_node_fields = kw.get('visible_node_fields',[])
|
visible_node_fields = kw.get('visible_node_fields',[])
|
||||||
invisible_node_fields = kw.get('invisible_node_fields',[])
|
invisible_node_fields = kw.get('invisible_node_fields',[])
|
||||||
node_fields_string = kw.get('node_fields_string',[])
|
node_fields_string = kw.get('node_fields_string',[])
|
||||||
connector_fields = kw.get('connector_fields',[])
|
connector_fields = kw.get('connector_fields',[])
|
||||||
connector_fields_string = kw.get('connector_fields_string',[])
|
connector_fields_string = kw.get('connector_fields_string',[])
|
||||||
|
|
||||||
bgcolors = {}
|
bgcolors = {}
|
||||||
shapes = {}
|
shapes = {}
|
||||||
bgcolor = kw.get('bgcolor','')
|
bgcolor = kw.get('bgcolor','')
|
||||||
shape = kw.get('shape','')
|
shape = kw.get('shape','')
|
||||||
|
|
||||||
if bgcolor:
|
if bgcolor:
|
||||||
for color_spec in bgcolor.split(';'):
|
for color_spec in bgcolor.split(';'):
|
||||||
if color_spec:
|
if color_spec:
|
||||||
colour, color_state = color_spec.split(':')
|
colour, color_state = color_spec.split(':')
|
||||||
bgcolors[colour] = color_state
|
bgcolors[colour] = color_state
|
||||||
|
|
||||||
if shape:
|
if shape:
|
||||||
for shape_spec in shape.split(';'):
|
for shape_spec in shape.split(';'):
|
||||||
if shape_spec:
|
if shape_spec:
|
||||||
shape_colour, shape_color_state = shape_spec.split(':')
|
shape_colour, shape_color_state = shape_spec.split(':')
|
||||||
shapes[shape_colour] = shape_color_state
|
shapes[shape_colour] = shape_color_state
|
||||||
|
|
||||||
ir_view = req.session.model('ir.ui.view')
|
ir_view = req.session.model('ir.ui.view')
|
||||||
graphs = ir_view.graph_get(id, model, node, connector, src_node, des_node, False,
|
graphs = ir_view.graph_get(int(id), model, node, connector, src_node, des_node, False,
|
||||||
(140, 180), req.session.context)
|
(140, 180), req.session.context)
|
||||||
|
|
||||||
nodes = graphs['nodes']
|
nodes = graphs['nodes']
|
||||||
transitions = graphs['transitions']
|
transitions = graphs['transitions']
|
||||||
isolate_nodes = {}
|
isolate_nodes = {}
|
||||||
|
for blnk_node in graphs['blank_nodes']:
|
||||||
for node in graphs['blank_nodes']:
|
isolate_nodes[blnk_node['id']] = blnk_node
|
||||||
isolate_nodes[node['id']] = node
|
|
||||||
else:
|
else:
|
||||||
y = map(lambda t: t['y'],filter(lambda x: x['y'] if x['x']==20 else None, nodes.values()))
|
y = map(lambda t: t['y'],filter(lambda x: x['y'] if x['x']==20 else None, nodes.values()))
|
||||||
y_max = (y and max(y)) or 120
|
y_max = (y and max(y)) or 120
|
||||||
|
|
||||||
connectors = {}
|
connectors = {}
|
||||||
list_tr = []
|
list_tr = []
|
||||||
|
|
||||||
|
@ -69,29 +59,29 @@ class DiagramView(View):
|
||||||
})
|
})
|
||||||
connector_tr = req.session.model(connector)
|
connector_tr = req.session.model(connector)
|
||||||
connector_ids = connector_tr.search([('id', 'in', list_tr)], 0, 0, 0, req.session.context)
|
connector_ids = connector_tr.search([('id', 'in', list_tr)], 0, 0, 0, req.session.context)
|
||||||
|
|
||||||
data_connectors =connector_tr.read(connector_ids, connector_fields, req.session.context)
|
data_connectors =connector_tr.read(connector_ids, connector_fields, req.session.context)
|
||||||
|
|
||||||
|
|
||||||
for tr in data_connectors:
|
for tr in data_connectors:
|
||||||
t = connectors.get(str(tr['id']))
|
t = connectors.get(str(tr['id']))
|
||||||
t.update({
|
t.update({
|
||||||
'source': tr[src_node][1],
|
'source': tr[src_node][1],
|
||||||
'destination': tr[des_node][1],
|
'destination': tr[des_node][1],
|
||||||
'options': {}
|
'options': {},
|
||||||
|
'signal': tr['signal']
|
||||||
})
|
})
|
||||||
|
|
||||||
for i, fld in enumerate(connector_fields):
|
for i, fld in enumerate(connector_fields):
|
||||||
t['options'][connector_fields_string[i]] = tr[fld]
|
t['options'][connector_fields_string[i]] = tr[fld]
|
||||||
|
|
||||||
fields = req.session.model('ir.model.fields')
|
fields = req.session.model('ir.model.fields')
|
||||||
field_ids = fields.search([('model', '=', model), ('relation', '=', node)], 0, 0, 0, req.session.context)
|
field_ids = fields.search([('model', '=', model), ('relation', '=', node)], 0, 0, 0, req.session.context)
|
||||||
field_data = fields.read(field_ids, ['relation_field'], req.session.context)
|
field_data = fields.read(field_ids, ['relation_field'], req.session.context)
|
||||||
|
|
||||||
node_act = req.session.model(node)
|
node_act = req.session.model(node)
|
||||||
search_acts = node_act.search([(field_data[0]['relation_field'], '=', id)], 0, 0, 0, req.session.context)
|
search_acts = node_act.search([(field_data[0]['relation_field'], '=', id)], 0, 0, 0, req.session.context)
|
||||||
data_acts = node_act.read(search_acts, invisible_node_fields + visible_node_fields, req.session.context)
|
data_acts = node_act.read(search_acts, invisible_node_fields + visible_node_fields, req.session.context)
|
||||||
|
|
||||||
for act in data_acts:
|
for act in data_acts:
|
||||||
n = nodes.get(str(act['id']))
|
n = nodes.get(str(act['id']))
|
||||||
if not n:
|
if not n:
|
||||||
|
@ -116,7 +106,7 @@ class DiagramView(View):
|
||||||
|
|
||||||
for i, fld in enumerate(visible_node_fields):
|
for i, fld in enumerate(visible_node_fields):
|
||||||
n['options'][node_fields_string[i]] = act[fld]
|
n['options'][node_fields_string[i]] = act[fld]
|
||||||
|
|
||||||
#to relate m2o field of transition to corresponding o2m in activity
|
#to relate m2o field of transition to corresponding o2m in activity
|
||||||
in_transition_field_id = fields.search([('relation', '=', connector), ('relation_field', '=', des_node), ('model', '=', node)], 0, 0, 0, req.session.context)
|
in_transition_field_id = fields.search([('relation', '=', connector), ('relation_field', '=', des_node), ('model', '=', node)], 0, 0, 0, req.session.context)
|
||||||
in_transition_field = fields.read(in_transition_field_id[0], ['name'], req.session.context)['name']
|
in_transition_field = fields.read(in_transition_field_id[0], ['name'], req.session.context)['name']
|
||||||
|
@ -124,4 +114,5 @@ class DiagramView(View):
|
||||||
out_transition_field_id = fields.search([('relation', '=', connector), ('relation_field', '=', src_node), ('model', '=', node)], 0, 0, 0, req.session.context)
|
out_transition_field_id = fields.search([('relation', '=', connector), ('relation_field', '=', src_node), ('model', '=', node)], 0, 0, 0, req.session.context)
|
||||||
out_transition_field = fields.read(out_transition_field_id[0], ['name'], req.session.context)['name']
|
out_transition_field = fields.read(out_transition_field_id[0], ['name'], req.session.context)['name']
|
||||||
|
|
||||||
return dict(nodes=nodes, conn=connectors, in_transition_field=in_transition_field, out_transition_field=out_transition_field)
|
id_model = req.session.model(model).read([id],['name'], req.session.context)[0]['name']
|
||||||
|
return dict(nodes=nodes, conn=connectors, id_model = id_model)
|
||||||
|
|
|
@ -58,7 +58,7 @@ var Graph = function() {
|
||||||
this.edgeFactory = new EdgeFactory();
|
this.edgeFactory = new EdgeFactory();
|
||||||
};
|
};
|
||||||
Graph.prototype = {
|
Graph.prototype = {
|
||||||
/*
|
/*
|
||||||
* add a node
|
* add a node
|
||||||
* @id the node's ID (string or number)
|
* @id the node's ID (string or number)
|
||||||
* @content (optional, dictionary) can contain any information that is
|
* @content (optional, dictionary) can contain any information that is
|
||||||
|
@ -83,7 +83,7 @@ Graph.prototype = {
|
||||||
// NOTE: Even directed edges are added to both nodes.
|
// NOTE: Even directed edges are added to both nodes.
|
||||||
t.edges.push(edge);
|
t.edges.push(edge);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* TODO to be implemented
|
/* TODO to be implemented
|
||||||
* Preserve a copy of the graph state (nodes, positions, ...)
|
* Preserve a copy of the graph state (nodes, positions, ...)
|
||||||
* @comment a comment describing the state
|
* @comment a comment describing the state
|
||||||
|
@ -154,19 +154,21 @@ Graph.Renderer.Raphael = function(element, graph, width, height) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dragging
|
* Dragging
|
||||||
*/
|
*/
|
||||||
this.isDrag = false;
|
this.isDrag = false;
|
||||||
this.dragger = function (e) {
|
this.dragger = function (e) {
|
||||||
this.dx = e.clientX;
|
if(e.detail < 2) {
|
||||||
this.dy = e.clientY;
|
this.dx = e.clientX;
|
||||||
selfRef.isDrag = this;
|
this.dy = e.clientY;
|
||||||
this.set && this.set.animate({"fill-opacity": .1}, 200) && this.set.toFront();
|
selfRef.isDrag = this;
|
||||||
e.preventDefault && e.preventDefault();
|
this.set && this.set.animate({"fill-opacity": .1}, 200) && this.set.toFront();
|
||||||
|
e.preventDefault && e.preventDefault();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var d = document.getElementById(element);
|
var d = document.getElementById(element);
|
||||||
d.onmousemove = function (e) {
|
d.onmousemove = function (e) {
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
|
@ -234,7 +236,7 @@ Graph.Renderer.Raphael.prototype = {
|
||||||
|
|
||||||
var shape;
|
var shape;
|
||||||
|
|
||||||
/* if a node renderer function is provided by the user, then use it
|
/* if a node renderer function is provided by the user, then use it
|
||||||
or the default render function instead */
|
or the default render function instead */
|
||||||
if(!node.render) {
|
if(!node.render) {
|
||||||
node.render = function(r, node) {
|
node.render = function(r, node) {
|
||||||
|
@ -305,7 +307,7 @@ Graph.Layout.Spring.prototype = {
|
||||||
}
|
}
|
||||||
this.layoutCalcBounds();
|
this.layoutCalcBounds();
|
||||||
},
|
},
|
||||||
|
|
||||||
layoutPrepare: function() {
|
layoutPrepare: function() {
|
||||||
for (i in this.graph.nodes) {
|
for (i in this.graph.nodes) {
|
||||||
var node = this.graph.nodes[i];
|
var node = this.graph.nodes[i];
|
||||||
|
@ -314,16 +316,16 @@ Graph.Layout.Spring.prototype = {
|
||||||
node.layoutForceX = 0;
|
node.layoutForceX = 0;
|
||||||
node.layoutForceY = 0;
|
node.layoutForceY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
layoutCalcBounds: function() {
|
layoutCalcBounds: function() {
|
||||||
var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity;
|
var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity;
|
||||||
|
|
||||||
for (i in this.graph.nodes) {
|
for (i in this.graph.nodes) {
|
||||||
var x = this.graph.nodes[i].layoutPosX;
|
var x = this.graph.nodes[i].layoutPosX;
|
||||||
var y = this.graph.nodes[i].layoutPosY;
|
var y = this.graph.nodes[i].layoutPosY;
|
||||||
|
|
||||||
if(x > maxx) maxx = x;
|
if(x > maxx) maxx = x;
|
||||||
if(x < minx) minx = x;
|
if(x < minx) minx = x;
|
||||||
if(y > maxy) maxy = y;
|
if(y > maxy) maxy = y;
|
||||||
|
@ -335,7 +337,7 @@ Graph.Layout.Spring.prototype = {
|
||||||
this.graph.layoutMinY = miny;
|
this.graph.layoutMinY = miny;
|
||||||
this.graph.layoutMaxY = maxy;
|
this.graph.layoutMaxY = maxy;
|
||||||
},
|
},
|
||||||
|
|
||||||
layoutIteration: function() {
|
layoutIteration: function() {
|
||||||
// Forces on nodes due to node-node repulsions
|
// Forces on nodes due to node-node repulsions
|
||||||
|
|
||||||
|
@ -345,17 +347,17 @@ Graph.Layout.Spring.prototype = {
|
||||||
for (var d in prev) {
|
for (var d in prev) {
|
||||||
var node2 = this.graph.nodes[prev[d]];
|
var node2 = this.graph.nodes[prev[d]];
|
||||||
this.layoutRepulsive(node1, node2);
|
this.layoutRepulsive(node1, node2);
|
||||||
|
|
||||||
}
|
}
|
||||||
prev.push(c);
|
prev.push(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forces on nodes due to edge attractions
|
// Forces on nodes due to edge attractions
|
||||||
for (var i = 0; i < this.graph.edges.length; i++) {
|
for (var i = 0; i < this.graph.edges.length; i++) {
|
||||||
var edge = this.graph.edges[i];
|
var edge = this.graph.edges[i];
|
||||||
this.layoutAttractive(edge);
|
this.layoutAttractive(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move by the given force
|
// Move by the given force
|
||||||
for (i in this.graph.nodes) {
|
for (i in this.graph.nodes) {
|
||||||
var node = this.graph.nodes[i];
|
var node = this.graph.nodes[i];
|
||||||
|
@ -367,7 +369,7 @@ Graph.Layout.Spring.prototype = {
|
||||||
if(xmove < -max) xmove = -max;
|
if(xmove < -max) xmove = -max;
|
||||||
if(ymove > max) ymove = max;
|
if(ymove > max) ymove = max;
|
||||||
if(ymove < -max) ymove = -max;
|
if(ymove < -max) ymove = -max;
|
||||||
|
|
||||||
node.layoutPosX += xmove;
|
node.layoutPosX += xmove;
|
||||||
node.layoutPosY += ymove;
|
node.layoutPosY += ymove;
|
||||||
node.layoutForceX = 0;
|
node.layoutForceX = 0;
|
||||||
|
@ -397,7 +399,7 @@ Graph.Layout.Spring.prototype = {
|
||||||
layoutAttractive: function(edge) {
|
layoutAttractive: function(edge) {
|
||||||
var node1 = edge.source;
|
var node1 = edge.source;
|
||||||
var node2 = edge.target;
|
var node2 = edge.target;
|
||||||
|
|
||||||
var dx = node2.layoutPosX - node1.layoutPosX;
|
var dx = node2.layoutPosX - node1.layoutPosX;
|
||||||
var dy = node2.layoutPosY - node1.layoutPosY;
|
var dy = node2.layoutPosY - node1.layoutPosY;
|
||||||
var d2 = dx * dx + dy * dy;
|
var d2 = dx * dx + dy * dy;
|
||||||
|
@ -414,7 +416,7 @@ Graph.Layout.Spring.prototype = {
|
||||||
var attractiveForce = (d2 - this.k * this.k) / this.k;
|
var attractiveForce = (d2 - this.k * this.k) / this.k;
|
||||||
if(edge.attraction == undefined) edge.attraction = 1;
|
if(edge.attraction == undefined) edge.attraction = 1;
|
||||||
attractiveForce *= Math.log(edge.attraction) * 0.5 + 1;
|
attractiveForce *= Math.log(edge.attraction) * 0.5 + 1;
|
||||||
|
|
||||||
node2.layoutForceX -= attractiveForce * dx / d;
|
node2.layoutForceX -= attractiveForce * dx / d;
|
||||||
node2.layoutForceY -= attractiveForce * dy / d;
|
node2.layoutForceY -= attractiveForce * dy / d;
|
||||||
node1.layoutForceX += attractiveForce * dx / d;
|
node1.layoutForceX += attractiveForce * dx / d;
|
||||||
|
@ -432,7 +434,7 @@ Graph.Layout.Ordered.prototype = {
|
||||||
this.layoutPrepare();
|
this.layoutPrepare();
|
||||||
this.layoutCalcBounds();
|
this.layoutCalcBounds();
|
||||||
},
|
},
|
||||||
|
|
||||||
layoutPrepare: function(order) {
|
layoutPrepare: function(order) {
|
||||||
for (i in this.graph.nodes) {
|
for (i in this.graph.nodes) {
|
||||||
var node = this.graph.nodes[i];
|
var node = this.graph.nodes[i];
|
||||||
|
@ -447,14 +449,14 @@ Graph.Layout.Ordered.prototype = {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
layoutCalcBounds: function() {
|
layoutCalcBounds: function() {
|
||||||
var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity;
|
var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity;
|
||||||
|
|
||||||
for (i in this.graph.nodes) {
|
for (i in this.graph.nodes) {
|
||||||
var x = this.graph.nodes[i].layoutPosX;
|
var x = this.graph.nodes[i].layoutPosX;
|
||||||
var y = this.graph.nodes[i].layoutPosY;
|
var y = this.graph.nodes[i].layoutPosY;
|
||||||
|
|
||||||
if(x > maxx) maxx = x;
|
if(x > maxx) maxx = x;
|
||||||
if(x < minx) minx = x;
|
if(x < minx) minx = x;
|
||||||
if(y > maxy) maxy = y;
|
if(y > maxy) maxy = y;
|
||||||
|
@ -470,7 +472,7 @@ Graph.Layout.Ordered.prototype = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usefull JavaScript extensions,
|
* usefull JavaScript extensions,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function log(a) {console.log&&console.log(a);}
|
function log(a) {console.log&&console.log(a);}
|
||||||
|
@ -491,14 +493,14 @@ Raphael.el.tooltip = function (tp) {
|
||||||
this.tp.o = {x: 0, y: 0};
|
this.tp.o = {x: 0, y: 0};
|
||||||
this.tp.hide();
|
this.tp.hide();
|
||||||
this.hover(
|
this.hover(
|
||||||
function(event){
|
function(event){
|
||||||
this.mousemove(function(event){
|
this.mousemove(function(event){
|
||||||
this.tp.translate(event.clientX -
|
this.tp.translate(event.clientX -
|
||||||
this.tp.o.x,event.clientY - this.tp.o.y);
|
this.tp.o.x,event.clientY - this.tp.o.y);
|
||||||
this.tp.o = {x: event.clientX, y: event.clientY};
|
this.tp.o = {x: event.clientX, y: event.clientY};
|
||||||
});
|
});
|
||||||
this.tp.show().toFront();
|
this.tp.show().toFront();
|
||||||
},
|
},
|
||||||
function(event){
|
function(event){
|
||||||
this.tp.hide();
|
this.tp.hide();
|
||||||
this.unmousemove();
|
this.unmousemove();
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
.openerp .diagram {
|
||||||
|
border: 1px solid #999;
|
||||||
|
-moz-border-radius: 8px;
|
||||||
|
-webkit-border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openerp .show_grid {
|
||||||
|
background: url("/web_diagram/static/src/img/grid.jpg") repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openerp .oe_diagram_pager {
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openerp .oe_diagram_buttons {
|
||||||
|
float: left;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
|
@ -1,179 +1,291 @@
|
||||||
/*---------------------------------------------------------
|
/*---------------------------------------------------------
|
||||||
* OpenERP web library
|
* OpenERP diagram library
|
||||||
*---------------------------------------------------------*/
|
*---------------------------------------------------------*/
|
||||||
|
|
||||||
openerp.web.diagram = function (openerp) {
|
openerp.web_diagram = function (openerp) {
|
||||||
|
QWeb.add_template('/web_diagram/static/src/xml/base_diagram.xml');
|
||||||
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
|
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
|
||||||
openerp.web.DiagramView = openerp.web.Widget.extend({
|
openerp.web.DiagramView = openerp.web.View.extend({
|
||||||
init: function(view_manager, session, element_id, dataset, view_id){
|
searchable: false,
|
||||||
this._super(session, element_id);
|
init: function(parent, element_id, dataset, view_id, options) {
|
||||||
this.view_manager = view_manager;
|
this._super(parent, element_id);
|
||||||
|
this.set_default_options(options);
|
||||||
|
this.view_manager = parent;
|
||||||
this.dataset = dataset;
|
this.dataset = dataset;
|
||||||
this.model = dataset.model;
|
this.model = this.dataset.model;
|
||||||
this.view_id = view_id;
|
this.view_id = view_id;
|
||||||
this.name = "";
|
this.domain = this.dataset._domain || [];
|
||||||
this.domain = this.dataset._domain ? this.dataset._domain: [];
|
this.context = {};
|
||||||
this.context = {};
|
this.ids = this.dataset.ids;
|
||||||
this.ids = this.dataset.ids;
|
},
|
||||||
|
start: function() {
|
||||||
console.log('data set>>',this.dataset)
|
return this.rpc("/web_diagram/diagram/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded);
|
||||||
},
|
},
|
||||||
start: function() {
|
|
||||||
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();});
|
||||||
|
},
|
||||||
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;
|
||||||
on_loaded: function(result) {
|
if(this.ids && this.ids.length) {
|
||||||
|
this.id = this.ids[self.dataset.index || 0];
|
||||||
var self = this;
|
}
|
||||||
if(this.ids && this.ids.length) {
|
|
||||||
this.id = this.ids[0];
|
this.fields_view = result.fields_view,
|
||||||
}
|
this.view_id = this.fields_view.view_id,
|
||||||
|
this.fields = this.fields_view.fields,
|
||||||
this.fields_view = result.fields_view;
|
this.nodes = this.fields_view.arch.children[0],
|
||||||
this.view_id = this.fields_view.view_id;
|
this.connectors = this.fields_view.arch.children[1],
|
||||||
this.name = this.fields_view.name;
|
this.node = this.nodes.attrs.object,
|
||||||
|
this.connector = this.connectors.attrs.object;
|
||||||
this.fields = this.fields_view.fields;
|
|
||||||
|
this.$element.html(QWeb.render("DiagramView", this));
|
||||||
var children = this.fields_view.arch.children;
|
|
||||||
/*
|
this.$element.find('div.oe_diagram_pager button[data-pager-action]').click(function() {
|
||||||
* For Nodes (Fields)
|
var action = $(this).data('pager-action');
|
||||||
*/
|
self.on_pager_action(action);
|
||||||
this.node = '';
|
});
|
||||||
this.bgcolor = '';
|
|
||||||
this.shape = '';
|
this.do_update_pager();
|
||||||
this.visible_fields_nodes = [];
|
|
||||||
this.invisible_fields_nodes = [];
|
// New Node,Edge
|
||||||
this.fields_nodes_string = [];
|
this.$element.find('#new_node.oe_diagram_button_new').click(function(){self.add_edit_node(null, self.node);});
|
||||||
|
this.$element.find('#new_edge.oe_diagram_button_new').click(function(){self.add_edit_node(null, self.connector);});
|
||||||
/*
|
|
||||||
* For Arraows(Connector)
|
this.$element.find('#toggle_grid').click(function() {
|
||||||
*/
|
self.$element.find('.diagram').toggleClass('show_grid');
|
||||||
this.connector = '';
|
});
|
||||||
this.src_node = '';
|
|
||||||
this.des_node = '';
|
if(this.id) {
|
||||||
this.connector_fields = [];
|
self.get_diagram_info();
|
||||||
this.fields_connector_string = [];
|
}
|
||||||
|
|
||||||
for(ch in children) {
|
},
|
||||||
if(children[ch]['tag'] == 'node') {
|
|
||||||
this.node = children[ch]['attrs']['object'];
|
get_diagram_info: function() {
|
||||||
this.bgcolor = children[ch]['attrs']['bgcolor'] || '';
|
var self = this;
|
||||||
this.shape = children[ch]['attrs']['shape'] || '';
|
var params = {
|
||||||
for(node_chld in children[ch]['children']) {
|
'id': this.id,
|
||||||
if (children[ch]['children'][node_chld]['tag'] = 'field') {
|
'model': this.model,
|
||||||
var ch_name = children[ch]['children'][node_chld]['attrs']['name'];
|
'node': this.node,
|
||||||
|
'connector': this.connector,
|
||||||
if (children[ch]['children'][node_chld]['attrs']['invisible']) {
|
'bgcolor': this.nodes.attrs.bgcolor,
|
||||||
if (children[ch]['children'][node_chld]['attrs']['invisible'] == 1 && children[ch]['children'][node_chld]['attrs']['invisible'] == '1') {
|
'shape': this.nodes.attrs.shape,
|
||||||
this.invisible_fields_nodes.push(ch_name)
|
'src_node': this.connectors.attrs.source,
|
||||||
}
|
'des_node': this.connectors.attrs.destination,
|
||||||
}
|
'visible_nodes': [],
|
||||||
else {
|
'invisible_nodes': [],
|
||||||
this.visible_fields_nodes.push(ch_name);
|
'node_fields': [],
|
||||||
var ch_node_string = this.fields[ch_name]['string'] || this.toTitleCase(ch_name);
|
'connectors': [],
|
||||||
this.fields_nodes_string.push(ch_node_string)
|
'connectors_fields': []
|
||||||
}
|
};
|
||||||
}
|
|
||||||
}
|
_.each(this.nodes.children, function(child) {
|
||||||
} else if(children[ch]['tag'] == 'arrow') {
|
if(child.attrs.invisible == '1')
|
||||||
this.connector = children[ch]['attrs']['object'];
|
params['invisible_nodes'].push(child.attrs.name);
|
||||||
this.src_node = children[ch]['attrs']['source'];
|
else {
|
||||||
this.des_node = children[ch]['attrs']['destination'];
|
params['visible_nodes'].push(child.attrs.name);
|
||||||
for (arrow_chld in children[ch]['children']) {
|
params['node_fields'].push(self.fields[child.attrs.name]['string']|| this.toTitleCase(child.attrs.name));
|
||||||
if (children[ch]['children'][arrow_chld]['tag'] = 'field') {
|
}
|
||||||
var arr_ch_name = children[ch]['children'][arrow_chld]['attrs']['name'];
|
});
|
||||||
var ch_node_string = this.fields[arr_ch_name]['string'] || this.toTitleCase(arr_ch_name);
|
|
||||||
this.fields_connector_string.push(ch_node_string);
|
_.each(this.connectors.children, function(conn) {
|
||||||
this.connector_fields.push(arr_ch_name);
|
params['connectors_fields'].push(self.fields[conn.attrs.name]['string']|| this.toTitleCase(conn.attrs.name));
|
||||||
}
|
params['connectors'].push(conn.attrs.name);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}
|
this.rpc(
|
||||||
this.$element.html(QWeb.render("DiagramView", {"fields_view": this.fields_view}));
|
'/web_diagram/diagram/get_diagram_info',params,
|
||||||
|
function(result) {
|
||||||
if(this.id) {
|
self.draw_diagram(result);
|
||||||
this.rpc(
|
}
|
||||||
'/web_diagram/diagram/get_diagram_info',
|
);
|
||||||
{
|
},
|
||||||
'id': this.id,
|
|
||||||
'model': this.model,
|
on_diagram_loaded: function(record) {
|
||||||
'bgcolor': this.bgcolor,
|
var id_record = record['id'];
|
||||||
'shape': this.shape,
|
if(id_record) {
|
||||||
'node': this.node,
|
this.id = id_record;
|
||||||
'connector': this.connector,
|
this.get_diagram_info();
|
||||||
'src_node': this.src_node,
|
}
|
||||||
'des_node': this.des_node,
|
},
|
||||||
'visible_node_fields': this.visible_fields_nodes,
|
|
||||||
'invisible_node_fields': this.invisible_fields_nodes,
|
draw_diagram: function(result) {
|
||||||
'node_fields_string': this.fields_nodes_string,
|
var diagram = new Graph();
|
||||||
'connector_fields': this.connector_fields,
|
|
||||||
'connector_fields_string': this.fields_connector_string
|
this.active_model = result['id_model'];
|
||||||
},
|
|
||||||
function(result) {
|
var res_nodes = result['nodes'];
|
||||||
self.draw_diagram(result);
|
var res_connectors = result['conn'];
|
||||||
}
|
|
||||||
)
|
//Custom logic
|
||||||
}
|
var self = this;
|
||||||
},
|
var renderer = function(r, n) {
|
||||||
|
var node;
|
||||||
draw_diagram: function(result) {
|
var set;
|
||||||
console.log('this>>>',this)
|
var shape = n.node.shape;
|
||||||
var g = new Graph();
|
if(shape == 'rectangle')
|
||||||
// var raphel = new
|
shape = 'rect';
|
||||||
this.in_transition_field = result['in_transition_field'];
|
node = r[shape](n.node.x, n.node.y).attr({
|
||||||
this.out_transition_field = result['out_transition_field'];
|
"fill": n.node.color
|
||||||
var res_nodes = result['nodes'];
|
}).dblclick(function() {
|
||||||
var res_connectors = result['conn'];
|
self.add_edit_node(n.node.id, self.node);
|
||||||
|
});
|
||||||
var render = function(r, n) {
|
set = r.set()
|
||||||
var set;
|
.push(node)
|
||||||
if (n.node.shape == 'ellipse') {
|
.push(
|
||||||
set = r.set().push(
|
r.text(n.node.x, n.node.y, (n.label || n.id))
|
||||||
r.ellipse(n.node.x - 30, n.node.y - 13, 40, 40).attr({
|
.attr({"cursor":"pointer"})
|
||||||
"fill": n.node.color,
|
.dblclick(function() {
|
||||||
r: "12px",
|
self.add_edit_node(n.node.id, self.node);
|
||||||
"stroke-width": n.distance == 0 ? "3px" : "1px"
|
})
|
||||||
})).push(r.text(n.node.x - 30, n.node.y - 10, (n.label || n.id)));
|
);
|
||||||
} else {
|
node.attr({cursor: "pointer"});
|
||||||
set = r.set().push(
|
|
||||||
r.rect(n.node.x-30, n.node.y-13, 60, 44).attr({"fill": n.node.color, r : "12px", "stroke-width" : n.distance == 0 ? "3px" : "1px" })).push(
|
if(shape == "ellipse")
|
||||||
r.text(n.point[0], n.point[1] + 10, (n.label || n.id) + "\n(" + (n.distance == undefined ? "Infinity" : n.distance) + ")"));
|
node.attr({rx: "40", ry: "20"});
|
||||||
|
else 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});
|
||||||
|
}
|
||||||
return set;
|
return set;
|
||||||
};
|
};
|
||||||
|
|
||||||
for(nd in res_nodes) {
|
_.each(res_nodes, function(res_node) {
|
||||||
var res_node = res_nodes[nd];
|
diagram.addNode(res_node['name'],{node: res_node,render: renderer});
|
||||||
g.addNode(res_node['name'],
|
});
|
||||||
{
|
|
||||||
node: res_node,
|
// Id for Path(Edges)
|
||||||
render: render
|
var edge_ids = [];
|
||||||
});
|
|
||||||
}
|
_.each(res_connectors, function(connector, index) {
|
||||||
|
edge_ids.push(index);
|
||||||
for(cr in res_connectors) {
|
diagram.addEdge(connector['source'], connector['destination'], {directed : true, label: connector['signal']});
|
||||||
var res_connector = res_connectors[cr];
|
});
|
||||||
g.addEdge(res_connector['source'], res_connector['destination']);
|
|
||||||
}
|
|
||||||
|
if ($('div#dia-canvas').children().length > 0) {
|
||||||
var layouter = new Graph.Layout.Spring(g);
|
$('div#dia-canvas').children().remove();
|
||||||
layouter.layout();
|
}
|
||||||
|
|
||||||
var renderer = new Graph.Renderer.Raphael('dia-canvas', g, 800, 800);
|
var layouter = new Graph.Layout.Ordered(diagram);
|
||||||
renderer.draw();
|
var render_diagram = new Graph.Renderer.Raphael('dia-canvas', diagram, $('div#dia-canvas').width(), $('div#dia-canvas').height());
|
||||||
},
|
|
||||||
|
_.each(diagram.edges, function(edge, index) {
|
||||||
do_show: function () {
|
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) {
|
||||||
|
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 : {
|
||||||
|
Cancel : function() {
|
||||||
|
$(this).dialog('destroy');
|
||||||
|
},
|
||||||
|
Save : 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',
|
||||||
|
auto_search : false,
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
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);
|
||||||
|
},
|
||||||
|
|
||||||
|
do_show: function () {
|
||||||
this.$element.show();
|
this.$element.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
do_hide: function () {
|
do_hide: function () {
|
||||||
this.$element.hide();
|
this.$element.hide();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<template>
|
||||||
|
<t t-name="DiagramView">
|
||||||
|
<div class="oe_diagram_header" t-att-id="element_id + '_header'">
|
||||||
|
<h2 class="oe_view_title"><t t-esc="fields_view.arch.attrs.string"/></h2>
|
||||||
|
<div class="oe_diagram_buttons">
|
||||||
|
<button type="button" id="new_node" class="oe_diagram_button_new">New Node</button>
|
||||||
|
<button type="button" id="new_edge" class="oe_diagram_button_new">New Edge</button>
|
||||||
|
<label>Show Grid:</label><input type="checkbox" id="toggle_grid" checked="checked"/>
|
||||||
|
</div>
|
||||||
|
<div class="oe_diagram_pager">
|
||||||
|
<button type="button" data-pager-action="first">First</button>
|
||||||
|
<button type="button" data-pager-action="previous"><<</button>
|
||||||
|
|
||||||
|
<span class="oe_pager_index">0</span> / <span class="oe_pager_count">0</span>
|
||||||
|
|
||||||
|
<button type="button" data-pager-action="next">>></button>
|
||||||
|
<button type="button" data-pager-action="last">Last</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="dia-canvas" class="diagram show_grid" style="overflow: auto;"></div>
|
||||||
|
</t>
|
||||||
|
</template>
|
Loading…
Reference in New Issue