Commit 20587cea authored by Jérome Perrin's avatar Jérome Perrin

graph editor in ready to merge state

parent b371063d
......@@ -177,7 +177,7 @@
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
<value> <string>page</string> </value>
</item>
<item>
<key> <string>data_url</string> </key>
......@@ -213,7 +213,7 @@
</item>
<item>
<key> <string>extra</string> </key>
<value> <string>style="width: 100%; height: 100%"</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>gadget_url</string> </key>
......
......@@ -112,7 +112,8 @@ class_definition = {\n
},\n
\'actbox_url\': {\n
\'type\': \'string\',\n
\'name\': \'URL of the action, variables will be substitued. XXX TODO: higher level ! just configure "script name" \'\n
\'name\': \'Action URL\',\n
\'description\': \'URL of the action, variables will be substitued. XXX TODO: higher level ! just configure "script name" \'\n
},\n
}\n
},\n
......
......@@ -177,7 +177,7 @@
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
<value> <string>page</string> </value>
</item>
<item>
<key> <string>data_url</string> </key>
......@@ -213,7 +213,7 @@
</item>
<item>
<key> <string>extra</string> </key>
<value> <string>style="width: 100%; height: 100%"</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>gadget_url</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31681694.27</string> </value>
<value> <string>ts31928725.88</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
......@@ -22,21 +22,21 @@
<key> <string>data</string> </key>
<value> <string>.graph_container {\n
position: relative;\n
margin: 20px auto;\n
font-size: 80%;\n
border: 1px solid #999;\n
\n
min-width: 400px;\n
min-height: 400px;\n
\n
overflow: auto;\n
border-radius: 10px;\n
overflow: hidden;\n
background-color: #eaedef;\n
text-align: center\n
text-align: center;\n
}\n
\n
.selected {\n
color: #bd0b0b!important\n
}\n
\n
.window,\n
.label {\n
background-color: #fff;\n
......@@ -143,7 +143,7 @@ path {\n
</item>
<item>
<key> <string>size</string> </key>
<value> <int>2422</int> </value>
<value> <int>2379</int> </value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31914157.58</string> </value>
<value> <string>ts31928462.63</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
......@@ -49,6 +49,7 @@
* less dependancies ( promise event listner ? )\n
* no more handlebars\n
* auto springy layout\n
* id should not always be modifiable\n
* drop zoom level\n
* rename draggable()\n
* factorize node & edge popup edition\n
......@@ -131,7 +132,12 @@
}\n
\n
function getDefaultEdgeClass(gadget) {\n
// TODO: use first edge class available in class_definition\n
var class_definition = gadget.props.data.class_definition;\n
for (var key in class_definition) {\n
if (class_definition.hasOwnProperty(key) && class_definition[key]._class === \'edge\') {\n
return key;\n
}\n
}\n
return "Dream.Edge";\n
}\n
\n
......@@ -276,32 +282,36 @@
gadget.notifyDataChanged();\n
}\n
\n
function updateElementData(gadget, node_id, data) {\n
var element_id = gadget.props.node_id_to_dom_element_id[node_id],\n
new_id = data.id;\n
if (data.data.name) {\n
$(gadget.props.element).find("#" + element_id).text(data.data.name).attr("title", data.data.name).append(\'<div class="ep"></div></div>\');\n
gadget.props.data.graph.node[node_id].name = data.data.name;\n
}\n
delete data.id;\n
$.extend(gadget.props.data.graph.node[node_id], data.data);\n
if (new_id && new_id !== node_id) {\n
gadget.props.data.graph.node[new_id] = gadget.props.data.graph.node[node_id];\n
delete gadget.props.data.graph.node[node_id];\n
gadget.props.node_id_to_dom_element_id[new_id] = gadget.props.node_id_to_dom_element_id[node_id];\n
delete gadget.props.node_id_to_dom_element_id[node_id];\n
delete gadget.props.data.graph.node[new_id].id;\n
$.each(gadget.props.data.graph.edge, function(k, v) {\n
if (v.source === node_id) {\n
v.source = new_id;\n
}\n
if (v.destination === node_id) {\n
v.destination = new_id;\n
}\n
});\n
}\n
gadget.notifyDataChanged();\n
}\n
function updateElementData(gadget, node_id, data) {\n
var element_id = gadget.props.node_id_to_dom_element_id[node_id],\n
new_id = data.id || data.data.id;\n
$(gadget.props.element).find("#" + element_id).text(data.data.name || new_id)\n
.attr("title", data.data.name || new_id)\n
.append(\'<div class="ep"></div></div>\');\n
\n
delete data.id;\n
\n
$.extend(gadget.props.data.graph.node[node_id], data.data);\n
if (new_id && new_id !== node_id) {\n
gadget.props.data.graph.node[new_id] = gadget.props.data.graph.node[node_id];\n
delete gadget.props.data.graph.node[node_id];\n
\n
gadget.props.node_id_to_dom_element_id[new_id] = gadget.props.node_id_to_dom_element_id[node_id];\n
delete gadget.props.node_id_to_dom_element_id[node_id];\n
\n
delete gadget.props.data.graph.node[new_id].id;\n
$.each(gadget.props.data.graph.edge, function (k, v) {\n
if (v.source === node_id) {\n
v.source = new_id;\n
}\n
if (v.destination === node_id) {\n
v.destination = new_id;\n
}\n
});\n
}\n
gadget.notifyDataChanged();\n
}\n
\n
\n
function addEdge(gadget, edge_id, edge_data) {\n
var overlays = [],\n
......@@ -729,7 +739,6 @@
this.props.erp5_key = data.key;\n
data = data.value;\n
}\n
jsplumb_instance = this.props.jsplumb_instance = jsPlumb.getInstance();\n
\n
this.props.main = this.props.element.querySelector(".graph_container");\n
/*\n
......@@ -739,28 +748,6 @@
}\n
});\n
*/\n
\n
jsplumb_instance.setRenderMode(jsplumb_instance.SVG);\n
jsplumb_instance.importDefaults({\n
HoverPaintStyle: {\n
strokeStyle: "#1e8151",\n
lineWidth: 2\n
},\n
Endpoint: ["Dot", {\n
radius: 2\n
}],\n
ConnectionOverlays: [\n
["Arrow", {\n
location: 1,\n
id: "arrow",\n
length: 14,\n
foldback: 0.8\n
}]\n
],\n
Container: this.props.main\n
});\n
draggable(gadget);\n
\n
if (data) {\n
this.props.data = JSON.parse(data);\n
// load the data\n
......@@ -771,11 +758,6 @@
addEdge(gadget, key, value);\n
});\n
}\n
\n
// XXX We won\'t have errors there in promise chain !\n
// it is too early to declare this is startService\n
waitForConnectionClick(gadget).fail(console.log);\n
\n
})\n
.declareMethod("getContent", function() {\n
var ret = {};\n
......@@ -787,9 +769,9 @@
return JSON.stringify(this.props.data);\n
})\n
.declareService(function() {\n
var gadget = this;\n
var gadget = this, jsplumb_instance;\n
this.props.main = this.props.element.querySelector(".graph_container");\n
this.props.jsplumb_instance = jsPlumb.getInstance();\n
this.props.jsplumb_instance = jsplumb_instance = jsPlumb.getInstance();\n
if (this.props.data) {\n
// load the data\n
$.each(this.props.data.graph.node, function(key, value) {\n
......@@ -799,7 +781,27 @@
addEdge(gadget, key, value);\n
});\n
}\n
\n
jsplumb_instance.setRenderMode(jsplumb_instance.SVG);\n
jsplumb_instance.importDefaults({\n
HoverPaintStyle: {\n
strokeStyle: "#1e8151",\n
lineWidth: 2\n
},\n
Endpoint: ["Dot", {\n
radius: 2\n
}],\n
ConnectionOverlays: [\n
["Arrow", {\n
location: 1,\n
id: "arrow",\n
length: 14,\n
foldback: 0.8\n
}]\n
],\n
Container: this.props.main\n
});\n
draggable(gadget);\n
\n
this.props.nodes_click_monitor = RSVP.Monitor();\n
return RSVP.all([waitForDrop(gadget),\n
waitForConnection(gadget),\n
......@@ -819,7 +821,7 @@
</item>
<item>
<key> <string>size</string> </key>
<value> <int>29429</int> </value>
<value> <int>29366</int> </value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts25570637.9</string> </value>
<value> <string>ts31928229.99</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
......@@ -22,13 +22,21 @@
<key> <string>data</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*global rJS, JSON, QUnit, jQuery, RSVP, console, setTimeout*/\n
/*global window, document, rJS, JSON, QUnit, jQuery, RSVP, console, setTimeout\n
\n
*/\n
(function(rJS, JSON, QUnit, RSVP, $) {\n
"use strict";\n
var start = QUnit.start, stop = QUnit.stop, test = QUnit.test, equal = QUnit.equal, ok = QUnit.ok, error_handler = function(e) {\n
console.error(e);\n
ok(false, e);\n
}, sample_class_definition = {\n
var start = QUnit.start,\n
stop = QUnit.stop,\n
test = QUnit.test,\n
equal = QUnit.equal,\n
ok = QUnit.ok,\n
error_handler = function(e) {\n
window.console.error(e);\n
ok(false, e);\n
},\n
sample_class_definition = {\n
edge: {\n
description: "Base definition for edge",\n
properties: {\n
......@@ -116,7 +124,11 @@
N2: {\n
_class: "Example.Node",\n
name: "Node 2",\n
shape: "circle"\n
shape: "circle",\n
coordinate: {\n
top: 0.3,\n
left: 0.4\n
}\n
}\n
}\n
}, sample_graph_not_connected = {\n
......@@ -146,7 +158,7 @@
edge: {}\n
}\n
});\n
QUnit.config.testTimeout = 5e3;\n
QUnit.config.testTimeout = 60000;\n
rJS(window).ready(function(g) {\n
test("Sample graph can be loaded and output is equal to input", function() {\n
var jsplumb_gadget;\n
......@@ -170,7 +182,7 @@
// more elegant way.\n
return jsplumb_gadget.getContent().then(function() {\n
// fake a drop event\n
var e = new Event("drop");\n
var e = new window.Event("drop");\n
e.dataTransfer = {\n
getData: function(type) {\n
// make sure we are called properly\n
......@@ -183,9 +195,9 @@
return jsplumb_gadget.getContent();\n
}).then(function(content) {\n
var node, graph = JSON.parse(content).graph;\n
equal(1, Object.keys(graph.node).length);\n
equal(1, Object.keys(graph.node).length, "There is one new node class");\n
node = graph.node[Object.keys(graph.node)[0]];\n
equal("Example.Node", node._class);\n
equal("Example.Node", node._class, "Node class is set to Example.?ode");\n
});\n
}\n
g.declareGadget("./index.html", {\n
......@@ -193,16 +205,14 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_empty_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("Node can be dragged", function() {\n
var jsplumb_gadget;\n
stop();\n
function runTest() {\n
return jsplumb_gadget.getContent().then(function() {\n
// 100 and 60 are about 10% of the #main div ( set by css, so this\n
// 100 and 60 are about 10% of the .graph_container div ( set by css, so this\n
// might change )\n
$("div[title=\'Node 1\']").simulate("drag", {\n
dx: 100,\n
......@@ -223,9 +233,7 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("Node properties can be edited", function() {\n
var jsplumb_gadget;\n
......@@ -275,9 +283,7 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("Node can be connected", function() {\n
var jsplumb_gadget;\n
......@@ -297,7 +303,7 @@
equal(2, Object.keys(graph.node).length, "We still have 2 nodes");\n
equal(1, Object.keys(graph.edge).length, "We have 1 edge");\n
edge = graph.edge[Object.keys(graph.edge)[0]];\n
// XXX how edge class would be set ? the first one from schema ?\n
// XXX how edge class would be set ? the first one from schema ? Yes ! TODO: update test\n
//equal("Example.Edge", edge._class, "Edge class is correct");\n
equal("N1", edge.source, "edge source is correct");\n
equal("N2", edge.destination, "edge destination is correct");\n
......@@ -308,9 +314,7 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_graph_not_connected);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("Node can be deleted", function() {\n
var jsplumb_gadget;\n
......@@ -356,11 +360,9 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("Node id can be changed (connections are updated and node" + " can be edited afterwards)", function() {\n
test("Node id can be changed (connections are updated and node can be edited afterwards)", function() {\n
var jsplumb_gadget;\n
stop();\n
function runTest() {\n
......@@ -405,9 +407,7 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("New node can be edited", function() {\n
var jsplumb_gadget, node_id;\n
......@@ -417,7 +417,7 @@
// more elegant way.\n
return jsplumb_gadget.getContent().then(function() {\n
// fake a drop event\n
var e = new Event("drop");\n
var e = new window.Event("drop");\n
e.dataTransfer = {\n
getData: function(type) {\n
// make sure we are called properly\n
......@@ -479,9 +479,7 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_empty_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
test("New node can be deleted", function() {\n
var jsplumb_gadget, node_id;\n
......@@ -491,7 +489,7 @@
// more elegant way.\n
return jsplumb_gadget.getContent().then(function() {\n
// fake a drop event\n
var e = new Event("drop");\n
var e = new window.Event("drop");\n
e.dataTransfer = {\n
getData: function(type) {\n
// make sure we are called properly\n
......@@ -546,9 +544,7 @@
}).then(function(new_gadget) {\n
jsplumb_gadget = new_gadget;\n
jsplumb_gadget.render(sample_data_empty_graph);\n
}).then(function() {\n
return RSVP.any([ jsplumb_gadget.startService(), runTest() ]);\n
}).fail(error_handler).always(start);\n
}).then(runTest).fail(error_handler).always(start);\n
});\n
});\n
})(rJS, JSON, QUnit, RSVP, jQuery);
......@@ -561,7 +557,7 @@
</item>
<item>
<key> <string>size</string> </key>
<value> <int>26487</int> </value>
<value> <int>26016</int> </value>
</item>
<item>
<key> <string>title</string> </key>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment