Commit 8127666c authored by Jérome Perrin's avatar Jérome Perrin

Update Graph Editor

* Fixes https://erp5js.nexedi.net/#/bug_module/20160609-11B02E6 and https://erp5js.nexedi.net/#/bug_module/20210517-F12266
* Support ERP5JS
* Improve test coverage
* Small CSS changes
* Fix bug editing business process when erp5_graph_editor was installed 

See merge request nexedi/erp5!1461
parents f359f267 3272990a
Pipeline #16667 passed with stage
in 0 seconds
......@@ -75,26 +75,20 @@
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
<string>my_jsplumb_graph</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list>
<string>my_jsplumb_graph</string>
</list>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_int_index</string>
<string>listbox_order_builder_title_list</string>
<string>listbox_delivery_builder_title_list</string>
</list>
<list/>
</value>
</item>
<item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>editable_columns</string>
<string>enabled</string>
<string>portal_types</string>
<string>sort</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>int_index</string>
<string>Index</string>
</tuple>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>predecessor_title</string>
<string>Predecessor</string>
</tuple>
<tuple>
<string>successor_title</string>
<string>Successor</string>
</tuple>
<tuple>
<string>order_builder_title_list</string>
<string>Order Builders</string>
</tuple>
<tuple>
<string>delivery_builder_title_list</string>
<string>Delivery Builders</string>
</tuple>
<tuple>
<string>trade_phase_title</string>
<string>Trade Phase</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list>
<tuple>
<string>int_index</string>
<string>int_index</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list>
<tuple>
<string>Business Link</string>
<string>Business Link</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list>
<tuple>
<string>int_index</string>
<string>ascending</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Business Links</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_delivery_builder_title_list</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox_delivery_builder_title_list</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_int_index</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox_int_index</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_order_builder_title_list</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox_order_builder_title_list</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -227,7 +227,7 @@
</item>
<item>
<key> <string>gadget_url</string> </key>
<value> <string>dream_graph_editor/jsplumb/index.html</string> </value>
<value> <string>gadget_graph_editor.html</string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
......@@ -235,7 +235,7 @@
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value> <string></string> </value>
<value> <string>iframe</string> </value>
</item>
<item>
<key> <string>renderjs_extra</string> </key>
......@@ -253,11 +253,11 @@
</item>
<item>
<key> <string>validator_field_id</string> </key>
<value> <string></string> </value>
<value> <string>my_core_mode_text_content_validator</string> </value>
</item>
<item>
<key> <string>validator_form_id</string> </key>
<value> <string></string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
</dictionary>
</value>
......
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>editable</string>
</list>
</value>
</item>
<item>
......@@ -69,6 +71,10 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_reference</string> </value>
......
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>editable</string>
</list>
</value>
</item>
<item>
......@@ -69,6 +71,10 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_title</string> </value>
......
......@@ -3,7 +3,6 @@ from Products.Formulator.Errors import FormValidationError
request = container.REQUEST
form = getattr(context, form_id)
edit_order = form.edit_order
try:
# Validate
form.validate_all_to_request(request, key_prefix='my_')
......@@ -16,7 +15,7 @@ except FormValidationError, validation_errors:
result['field_errors'][key] = value.error_text
return form()
(kw, encapsulated_editor_list), action = context.Base_edit(form_id, silent_mode=1)
(kw, encapsulated_editor_list), _ = context.Base_edit(form_id, silent_mode=1)
assert not encapsulated_editor_list
context.setProperties(
......
from Products.ERP5Type.Message import translateString
import json
portal = context.getPortalObject()
# if a graph has been saved, we use this info for node coordinates.
position_graph = context.getProperty('jsplumb_graph')
......
from Products.ERP5Type.Message import translateString
import json
portal = context.getPortalObject()
# if a graph has been saved, we use this info for node coordinates.
position_graph = context.getProperty('jsplumb_graph')
......@@ -37,11 +35,8 @@ def getWorkflowGraph(workflow):
'transition_id': transition.getId(), # used for edition.
'path': transition.getPath()
})
else:
# user action
transition_list.append(transition)
if transition_list != []:
if transition_list:
graph['edge']['transition_to_%s' % (state.getId())] = {
'_class':'workflow.transition',
'source':state.getId(),
......
......@@ -4,50 +4,22 @@
<meta charset="utf-8">
<link rel="stylesheet" href="../lib/jquery-ui.css">
<link rel="stylesheet" href="jsplumb.css">
<title>JSPlumb gadget</title>
<title>JSPlumb public gadget (for qunit tests)</title>
<!--
FIXME: renderjs fails if we include renderjs.js twice (this one has a different URL from ERP5's one)
The gadget for test is used with "public" sandbox, so we should not include javascripts again.
The following scripts must have been included by the parent page:
<script src="renderjs.js" type="text/javascript"></script>
<script src="rsvp.js" type="text/javascript"></script>
-->
<!--
FIXME: Including jQuery twice cause the jsplumb to be loaded twice.
For now we assume that it has already been loaded at this point.
<script src="../lib/jquery.js" type="text/javascript"></script>
-->
<script src="../lib/jquery-ui.js" type="text/javascript"></script>
<script src="../lib/jquery.jsplumb.js" type="text/javascript"></script>
<script src="../lib/handlebars.min.js" type="text/javascript"></script>
<script src="seedrandom.js" type="text/javascript"></script>
<script src="../lib/springy.js" type="text/javascript"></script>
<script src="../dream/mixin_promise.js" type="text/javascript"></script>
<script src="jsplumb.js" type="text/javascript"></script>
<script id="node-template" type="text/x-handlebars-template">
<div class="window {{class}}"
id="{{element_id}}"
title="{{title}}">
<a href="{{name_href}}">{{name}}</a>
<div class="ep"></div>
</div>
</script>
<script id="popup-edit-template" type="text/x-handlebars-template">
<div id="edit-popup" data-position-to="origin">
<div data-role="header" data-theme="a">
<h1 class="node_class">Edit properties</h1>
<!-- XXX add this for jquery mobile version.
<a href="#" data-rel="back" class="ui-btn ui-corner-all ui-shadow ui-btn-a ui-icon-delete ui-btn-icon-notext ui-btn-right">Close</a>
-->
</div>
<br/>
<form class="ui-content">
<fieldset></fieldset>
<input type="button" value="Delete" class="graph_editor_delete_button">
<input type="submit" value="Validate" class="graph_editor_validate_button">
</form>
</div>
</script>
</head>
<body>
<div class="graph_container"></div>
......
body {
margin: 0px;
}
.graph_container {
position: relative;
font-size: 80%;
border: 1px solid #999;
min-width: 400px;
min-height: 1200px;
font-size: 0.8em;
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #eaedef;
text-align: center;
}
.selected {
color: #bd0b0b!important
font-family: helvetica;
}
.window,
......@@ -26,6 +25,7 @@
-webkit-box-shadow: 2px 2px 19px #aaa;
-moz-box-shadow: 2px 2px 19px #aaa
}
path,
._jsPlumb_endpoint {
cursor: pointer
......@@ -46,6 +46,11 @@ path,
._jsPlumb_overlay {
z-index: 23
}
._jsPlumb_overlay._jsPlumb_hover {
z-index: 25!important;
font-size: 1.2em;
font-weight: bold;
}
._jsPlumb_connector._jsPlumb_hover {
z-index: 21!important
}
......@@ -58,8 +63,7 @@ path,
filter: alpha(opacity=80);
background-color: #fff;
color: #000;
font-family: helvetica;
padding: .5em
padding: .5em;
}
.window,
.dummy_window {
......@@ -69,12 +73,9 @@ path,
box-sizing: border-box;
position: absolute;
color: #000;
font-family: serif;
font-style: italic;
padding-top: .9em;
font-size: .9em;
cursor: move;
font-size: 11px;
-webkit-transition: background-color .1s ease-in;
-moz-transition: background-color .1s ease-in;
transition: background-color .1s ease-in;
......@@ -83,13 +84,15 @@ path,
.window:hover {
background-color: #5c96bc;
background-image: none;
color: #fff
color: #fff;
font-weight: bold;
}
.dummy_window {
position: absolute;
top: 0;
left: 0;
visibility: hidden
visibility: hidden;
z-index: -1;
}
.ep {
position: absolute;
......@@ -109,8 +112,10 @@ path,
.dragHover {
background-color: #1e8151;
background-image: none;
color: #fff
color: #fff;
font-weight: bold;
}
path {
cursor: pointer
}
\ No newline at end of file
......@@ -22,7 +22,7 @@
(function (RSVP, rJS, $, jsPlumb, Handlebars, loopEventListener, promiseEventListener, DOMParser, Springy) {
"use strict";
/* TODO:
* less dependancies ( promise event listener ? )
* less dependencies ( promise event listener ? )
* no more handlebars
* id should not always be modifiable
* drop zoom level
......@@ -31,9 +31,30 @@
*/
var gadget_klass = rJS(window);
var domParser = new DOMParser();
var node_template_source = gadget_klass.__template_element.getElementById("node-template").innerHTML;
var node_template = Handlebars.compile(node_template_source);
var popup_edit_template = gadget_klass.__template_element.getElementById("popup-edit-template").innerHTML;
var node_template = Handlebars.compile(
' <div class="window {{class}}"'
+ ' id="{{element_id}}"'
+ ' title="{{title}}">'
+ ' {{name}}'
+ ' <div class="ep"></div>'
+ '</div>'
);
var popup_edit_template = (
' <div id="edit-popup" data-position-to="origin">'
+ ' <div data-role="header" data-theme="a">'
+ ' <h1 class="node_class">Edit properties</h1>'
+ ' <!-- XXX add this for jquery mobile version.'
+ ' <a href="#" data-rel="back" class="ui-btn ui-corner-all ui-shadow ui-btn-a ui-icon-delete ui-btn-icon-notext ui-btn-right">Close</a>'
+ ' -->'
+ ' </div>'
+ ' <br/>'
+ ' <form class="ui-content">'
+ ' <fieldset></fieldset>'
+ ' <input type="button" value="Delete" class="graph_editor_delete_button">'
+ ' <input type="submit" value="Validate" class="graph_editor_validate_button">'
+ ' </form>'
+ '</div>'
);
function layoutGraph(graph_data) {
// Promise returning the graph once springy calculated the layout.
......@@ -204,8 +225,8 @@
function updateConnectionData(gadget, connection, remove) {
if (connection.ignoreEvent) {
// this hack is for edge edition. Maybe there I missed one thing and
// there is a better way.
// this hack is for edge edition and when the graph is re-rendered.
// Maybe there I missed one thing and there is a better way.
return;
}
if (remove) {
......@@ -353,25 +374,11 @@
function addEdge(gadget, edge_id, edge_data) {
var overlays = [];
var connection;
var label = '';
if (edge_data.name) {
label = edge_data.name;
if (edge_data.path) {
label = label.link(edge_data.path);
}
}
if (edge_data.name_path_dict) {
var linked_name_list = [];
for (var name in edge_data.name_path_dict) {
linked_name_list.push(name.link(edge_data.name_path_dict[name]));
}
label = linked_name_list.join(', ');
}
if (label) {
overlays = [
["Label", {
cssClass: "l1 component label",
label: label
label: edge_data.name
}]
];
}
......@@ -491,6 +498,82 @@
return clone(expanded_class_definition);
}
function openEdgeEditionDialog(gadget, connection) {
var edge_id = connection.id;
var edge_data = gadget.props.data.graph.edge[edge_id];
var edit_popup = $(gadget.props.element).find("#popup-edit-template");
var schema;
var fieldset_element;
var delete_promise;
var class_definition = gadget.props.data.class_definition[edge_data._class];
if (class_definition === undefined) {
return;
}
schema = expandSchema(class_definition, gadget.props.data);
// We do not edit source & destination on edge this way.
delete schema.properties.source;
delete schema.properties.destination;
gadget.props.element.insertAdjacentHTML("beforeend", popup_edit_template);
edit_popup = $(gadget.props.element).find("#edit-popup");
edit_popup.find(".node_class").text(connection.name || connection._class);
fieldset_element = edit_popup.find("fieldset")[0];
edit_popup.dialog();
edit_popup.show();
function save_promise(fieldset_gadget) {
return new RSVP.Queue().push(function () {
return promiseEventListener(edit_popup.find(".graph_editor_validate_button")[0], "click", false);
}).push(function (evt) {
var data = {
id: $(evt.target[1]).val(),
data: {}
};
return fieldset_gadget.getContent().then(function (r) {
$.extend(data.data, gadget.props.data.graph.edge[connection.id]);
$.extend(data.data, r);
// to redraw, we remove the edge and add again.
// but we want to disable events on connection, since event
// handling promise are executed asynchronously in undefined order,
// we cannot just remove and /then/ add, because the new edge is
// added before the old is removed.
connection.ignoreEvent = true;
gadget.props.jsplumb_instance.detach(connection);
addEdge(gadget, r.id, data.data);
});
});
}
delete_promise = new RSVP.Queue().push(function () {
return promiseEventListener(edit_popup.find(".graph_editor_delete_button")[0], "click", false);
}).push(function () {
// connectionDetached event will remove the edge from data
gadget.props.jsplumb_instance.detach(connection);
});
return gadget.declareGadget("dream_graph_editor/fieldset/index.html", {
element: fieldset_element,
scope: "fieldset"
}).push(function (fieldset_gadget) {
return RSVP.all([fieldset_gadget, fieldset_gadget.render({
value: edge_data,
property_definition: schema
}, edge_id)]);
}).push(function (fieldset_gadget) {
edit_popup.dialog("open");
return fieldset_gadget[0];
}).push(function (fieldset_gadget) {
fieldset_gadget.startService(); // XXX
return fieldset_gadget;
}).push(function (fieldset_gadget) {
// Expose the dialog handling promise so that we can wait for it in
// test.
gadget.props.dialog_promise = RSVP.any([save_promise(fieldset_gadget, edge_id), delete_promise]);
return gadget.props.dialog_promise;
}).push(function () {
edit_popup.dialog("close");
edit_popup.remove();
delete gadget.props.dialog_promise;
});
}
function openNodeEditionDialog(gadget, element) {
var node_id = getNodeId(gadget, element.id);
var node_data = gadget.props.data.graph.node[node_id];
......@@ -544,7 +627,7 @@
}).push(function () {
return removeElement(gadget, node_id);
});
return gadget.declareGadget("../fieldset/index.html", {
return gadget.declareGadget("dream_graph_editor/fieldset/index.html", {
element: fieldset_element,
scope: "fieldset"
}).push(function (fieldset_gadget) {
......@@ -588,6 +671,12 @@
});
}
function waitForConnectionClick(gadget) {
return loopJsplumbBind(gadget, "click", function (connection) {
return openEdgeEditionDialog(gadget, connection);
});
}
function addNode(gadget, node_id, node_data) {
var render_element = $(gadget.props.main);
var class_definition = gadget.props.data.class_definition[node_data._class];
......@@ -612,8 +701,7 @@
"class": node_data._class.replace(".", "-"),
element_id: dom_element_id,
title: node_data.name || node_data.id,
name: node_data.name || node_data.id,
name_href: node_data.path
name: node_data.name || node_data.id
}), "text/html").querySelector(".window");
render_element.append(domElement);
box = $(gadget.props.element).find("#" + dom_element_id);
......@@ -623,10 +711,6 @@
}
box.css("top", absolute_position[1]);
box.css("left", absolute_position[0]);
if (node_data.is_initial_state) {
box.css("border", "double #000000");
box.css("font-weight", "bold");
}
updateNodeStyle(gadget, dom_element_id);
draggable(gadget);
// XXX make only this element draggable.
......@@ -731,6 +815,20 @@
}
});
*/
// reset previous graph, if any.
if ($(".window", this.props.element).length) {
$.each(
// disable the "delete" event, otherwise after render load the
// graph, loopJsplumbBind events will process the connection deleted
// events
this.props.jsplumb_instance.getAllConnections(),
function (i, connection) {
connection.ignoreEvent = true;
});
this.props.jsplumb_instance.reset();
$(".window", this.props.element).remove();
}
if (data) {
this.props.data = JSON.parse(data);
......@@ -803,7 +901,8 @@
return RSVP.all([
waitForDrop(gadget),
waitForConnection(gadget),
waitForConnectionDetached(gadget)
waitForConnectionDetached(gadget),
waitForConnectionClick(gadget)
]);
});
......
......@@ -296,7 +296,7 @@
jsplumb_gadget.render(sample_data_graph);
}).then(runTest).fail(error_handler).always(start);
});
test("Node can be connected", function () {
test("Nodes can be connected", function () {
var jsplumb_gadget;
stop();
function runTest() {
......@@ -308,6 +308,9 @@
source: node1.id,
target: node2.id
});
// .connect insternal API is asynchronous, but there's no way to wait for the event to be processed.
// for now we just wait for a short delay
return RSVP.delay(1e3);
}).then(function () {
return jsplumb_gadget.getContent();
}).then(function (content) {
......@@ -588,5 +591,24 @@
});
}).fail(error_handler).always(start);
});
test("Gadget can be rendered multiple times", function () {
var jsplumb_gadget;
stop();
g.declareGadget("./index.html", {
element: document.querySelector("#test-element")
}).then(function (new_gadget) {
jsplumb_gadget = new_gadget;
return jsplumb_gadget.render(sample_data_graph);
}).then(function () {
return jsplumb_gadget.getContent();
}).then(function () {
return jsplumb_gadget.render(sample_data_graph);
}).then(function () {
return jsplumb_gadget.getContent();
}).then(function (content) {
equal(sample_data_graph, content);
equal($(".window", document.querySelector("#test-element")).length, 2, "Graph is rendered only once");
}).fail(error_handler).always(start);
});
});
}(rJS, JSON, QUnit, RSVP, jQuery));
\ No newline at end of file
......@@ -24,13 +24,6 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
// Nexedi patch: use seedrandom instead of Math.random to always get the same
// graph representation this will in order to be able to use seed and thus
// get the same set of random number, used to set the place of the graph nodes
var seeded_random = new Math.seedrandom('Using seedrandom for getting same set'
+ 'of pseudorandom numbers.');
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
......@@ -584,7 +577,7 @@ var seeded_random = new Math.seedrandom('Using seedrandom for getting same set'
};
Vector.random = function() {
return new Vector(10.0 * (seeded_random() - 0.5), 10.0 * (seeded_random() - 0.5));
return new Vector(10.0 * (Math.random() - 0.5), 10.0 * (Math.random() - 0.5));
};
Vector.prototype.add = function(v2) {
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="dream_graph_editor/lib/jquery-ui.css">
<link rel="stylesheet" href="dream_graph_editor/jsplumb/jsplumb.css">
<title>Graph Editor</title>
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="dream_graph_editor/lib/jquery.js" type="text/javascript"></script>
<script src="dream_graph_editor/lib/jquery-ui.js" type="text/javascript"></script>
<script src="dream_graph_editor/lib/jquery.jsplumb.js" type="text/javascript"></script>
<script src="dream_graph_editor/lib/handlebars.min.js" type="text/javascript"></script>
<script src="dream_graph_editor/lib/springy.js" type="text/javascript"></script>
<script src="dream_graph_editor/dream/mixin_promise.js" type="text/javascript"></script>
<script src="dream_graph_editor/jsplumb/jsplumb.js" type="text/javascript"></script>
<body>
<div class="graph_container"></div>
<div class="dummy_window"></div>
</body>
</html>
......@@ -6,17 +6,13 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Cacheable__manager_id</string> </key>
<value> <string>http_cache</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>seedrandom.js</string> </value>
<value> <string>gadget_graph_editor.html</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
......
......@@ -2,8 +2,6 @@ import json
business_process = sci['object']
graph = business_process.getProperty('jsplumb_graph')
assert graph
if graph:
portal = business_process.getPortalObject()
trade_state_dict = dict(start=None, end=None)
......
......@@ -13,7 +13,11 @@ Run existing qunit test in zelenium framework, to easily integrate it in current
<td tal:content="string:${context/portal_url}/dream_graph_editor/jsplumb/test.html"></td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Running</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Tests completed in </td>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Image" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>testWorkflowGraph-reference-snapshot-1.png</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>image/png</string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>284</int> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>1127</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testWorkflowGraph</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode>Workflow Graph</unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title tal:content="template/title"></title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4" tal:content="template/title">
</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td tal:content="string:${context/portal_url}/portal_workflow/validation_workflow/Workflow_viewGraph"></td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-editable="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>//div[@data-gadget-editable="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@class, "workflow-state")][4]</td>
<td></td>
</tr>
<tr>
<td>pause</td>
<td>1000</td>
<td></td>
</tr>
<tr><td colspan="3"><b>Verify the rendering of the graph matches our reference snapshot</b></td></tr>
<tr>
<td>verifyImageMatchSnapshot</td>
<td>//body</td>
<td>1</td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertPortalStatusMessage</td>
<td>Data updated.</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -233,7 +233,7 @@
</item>
<item>
<key> <string>gadget_url</string> </key>
<value> <string>dream_graph_editor/jsplumb/index.html</string> </value>
<value> <string>gadget_graph_editor.html</string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
......@@ -241,7 +241,7 @@
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value> <string></string> </value>
<value> <string>iframe</string> </value>
</item>
<item>
<key> <string>renderjs_extra</string> </key>
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
<value> <unicode>Test Item View Tracking List</unicode> </value>
</item>
</dictionary>
</pickle>
......
......@@ -2,17 +2,17 @@
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Item View Tracking List</title>
<title tal:content="template/title"></title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">TTest Item View Tracking List/td></tr>
<tr><td rowspan="1" colspan="3" tal:content="template/title"></td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForItemRenderjsUi/macros/init" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForItemRenderjsUi/macros/prepare_data" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForItemRenderjsUi/macros/view_item_tracking_list" />
<tal:block metal:use-macro="here/Zuite_viewCommonTemplateForItemRenderjsUi/macros/init" />
<tal:block metal:use-macro="here/Zuite_viewCommonTemplateForItemRenderjsUi/macros/prepare_data" />
<tal:block metal:use-macro="here/Zuite_viewCommonTemplateForItemRenderjsUi/macros/view_item_tracking_list" />
</tbody></table>
</body>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_createItemRJSZuiteItemAndPackingList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -54,7 +54,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ItemRJSZuite_deleteData</string> </value>
<value> <string>ERP5Site_deleteItemRJSZuiteData</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -63,7 +63,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Zuite_CommonTemplateForItemRenderjsUi</string> </value>
<value> <string>Zuite_viewCommonTemplateForItemRenderjsUi</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
......
......@@ -21,7 +21,7 @@
</tr>
<tr>
<td>open</td>
<td>${base_url}/ItemRJSZuite_deleteData</td>
<td>${base_url}/ERP5Site_deleteItemRJSZuiteData</td>
<td></td>
</tr>
<tr>
......@@ -35,13 +35,13 @@
</tal:block>
<tal:block metal:define-macro="prepare_data">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForItemRenderjsUi/macros/delete_data" />
<tal:block metal:use-macro="here/Zuite_viewCommonTemplateForItemRenderjsUi/macros/delete_data" />
<tr>
<td colspan="3"><b>Create Item Test Data</b></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/ItemRJSZuite_createItemAndPackingList</td>
<td>${base_url}/ERP5Site_createItemRJSZuiteItemAndPackingList</td>
<td></td>
</tr>
<tr>
......@@ -86,6 +86,29 @@
<td>Purchase Packing List Line</td>
<td></td>
</tr>
<!-- Graph editor to visualize tracking -->
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>//div[@data-gadget-scope="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@class, "node")][2]</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
<tal:block tal:define="click_configuration python: {'text': 'Sale Packing List Line'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_on_page_link" />
</tal:block>
......
erp5_item
erp5_web_renderjs_ui_test
erp5_graph_editor
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testBusinessProcess</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode>Test Business Process</unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title tal:content="template/title"></title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4" tal:content="template/title"></td></tr>
</thead>
<tbody tal:define="init_method string:Zuite_createBusinessProcessForTradeZuite;">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/business_process_module/test_trade_ui_test_business_process?editable=true</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testBusinessProcessGraph</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode>Test Business Process Graph</unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title tal:content="template/title"></title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4" tal:content="template/title"></td></tr>
</thead>
<tbody tal:define="init_method string:Zuite_createBusinessProcessForTradeZuite;">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/business_process_module/test_trade_ui_test_business_process?editable=true</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<!-- }}} -->
<tal:block tal:define="click_configuration python: {'text': 'Views'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_on_header_link" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="click_configuration python: {'text': 'Graph Editor'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_on_page_link" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>//div[@data-gadget-scope="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@class, "erp5-business_process")][5]</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>//div[@data-gadget-scope="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@class, "erp5-business_process")][5]</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//div[contains(@class, "erp5-business_process")][6]</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testBusinessProcess</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode>Test Business Process</unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title tal:content="template/title"></title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4" tal:content="template/title"></td></tr>
</thead>
<tbody tal:define="init_method string:Zuite_createBusinessProcessForTradeZuite;">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/init" />
<!-- }}} -->
<tr>
<td>open</td>
<td>${base_url}/business_process_module/test_trade_ui_test_business_process/</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertPortalStatusMessage</td>
<td>Data updated.</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testBusinessProcessGraph</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode>Test Business Process Graph</unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title tal:content="template/title"></title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4" tal:content="template/title"></td></tr>
</thead>
<tbody tal:define="init_method string:Zuite_createBusinessProcessForTradeZuite;">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/init" />
<!-- }}} -->
<tr>
<td>open</td>
<td>${base_url}/business_process_module/test_trade_ui_test_business_process/BusinessProcess_viewGraphEditor</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-editable="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>//div[@data-gadget-editable="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@class, "erp5-business_process")][5]</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertPortalStatusMessage</td>
<td>Data updated.</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-editable="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>//div[@data-gadget-editable="field_my_jsplumb_graph"]//iframe</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@class, "erp5-business_process")][5]</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
portal = context.getPortalObject()
# Create trade states
if getattr(portal.portal_categories.trade_state, 'erp5_trade_ui_test_ts', None) is None:
portal.portal_categories.trade_state.newContent(
id='erp5_trade_ui_test_ts'
)
portal.portal_categories.trade_state.erp5_trade_ui_test_ts.newContent(
id='delivered',
title='Delivered'
)
portal.portal_categories.trade_state.erp5_trade_ui_test_ts.newContent(
id='invoiced',
title='Invoiced'
)
# Create trade phases
if getattr(portal.portal_categories.trade_phase, 'erp5_trade_ui_test_tp', None) is None:
portal.portal_categories.trade_phase.newContent(
id='erp5_trade_ui_test_tp'
)
portal.portal_categories.trade_phase.erp5_trade_ui_test_tp.newContent(
id='delivery',
title='Delivery'
)
portal.portal_categories.trade_phase.erp5_trade_ui_test_tp.newContent(
id='invoicing',
title='Invoicing'
)
# Create business process
test_trade_ui_test_client = portal.business_process_module.newContent(
id='test_trade_ui_test_business_process')
test_trade_ui_test_client.newContent(
portal_type='Business Link',
completed_state_list=('delivered', 'stopped'),
frozen_state_list=('delivered', 'stopped'),
predecessor_value=None,
successor_value=portal.portal_categories.trade_state.erp5_trade_ui_test_ts.delivered,
trade_phase_value=portal.portal_categories.trade_phase.erp5_trade_ui_test_tp.delivery,
title='Deliver'
)
test_trade_ui_test_client.newContent(
portal_type='Business Link',
completed_state_list=('delivered', 'stopped'),
frozen_state_list=('delivered', 'stopped'),
predecessor_value=portal.portal_categories.trade_state.erp5_trade_ui_test_ts.delivered,
successor_value=portal.portal_categories.trade_state.erp5_trade_ui_test_ts.invoiced,
trade_phase_value=portal.portal_categories.trade_phase.erp5_trade_ui_test_tp.invoicing,
title='Invoice'
)
# XXX not sure we need such links
test_trade_ui_test_client.newContent(
portal_type='Business Link',
completed_state_list=('delivered', 'stopped'),
frozen_state_list=('delivered', 'stopped'),
predecessor_value=portal.portal_categories.trade_state.erp5_trade_ui_test_ts.invoiced,
successor_value=None,
trade_phase_value=portal.portal_categories.trade_phase.erp5_trade_ui_test_tp.invoicing,
title='Finish'
)
return "Data Created."
......@@ -54,7 +54,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ItemRJSZuite_createItemAndPackingList</string> </value>
<value> <string>Zuite_createBusinessProcessForTradeZuite</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -8,6 +8,7 @@ object_value_list = [
getattr(portal.organisation_module, 'test_trade_ui_test_client', None),
getattr(portal.person_module, 'test_trade_ui_test_supplier', None),
getattr(portal.person_module, 'test_trade_ui_test_client', None),
getattr(portal.business_process_module, 'test_trade_ui_test_business_process', None),
] + [
getattr(portal.getDefaultModule(portal_type), "erp5_trade_ui_test_trade_condition" + suffix, None)
for portal_type in ("Internal Trade Condition", "Purchase Trade Condition", "Sale Trade Condition")
......
erp5_pdm_ui_test
erp5_graph_editor
erp5_trade
erp5_ui_test
\ No newline at end of file
......@@ -72,7 +72,9 @@
<item>
<key> <string>center</string> </key>
<value>
<list/>
<list>
<string>my_title</string>
</list>
</value>
</item>
<item>
......@@ -84,9 +86,7 @@
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_title</string>
</list>
<list/>
</value>
</item>
<item>
......
......@@ -144,9 +144,7 @@
</item>
<item>
<key> <string>gadget_url</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
......@@ -160,6 +158,10 @@
<key> <string>js_sandbox</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>renderjs_extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
......@@ -168,6 +170,14 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>validator_field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>validator_form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -221,7 +231,7 @@
</item>
<item>
<key> <string>gadget_url</string> </key>
<value> <string></string> </value>
<value> <string>gadget_graph_editor.html</string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
......@@ -233,7 +243,13 @@
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value> <string></string> </value>
<value> <string>iframe</string> </value>
</item>
<item>
<key> <string>renderjs_extra</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>required</string> </key>
......@@ -243,6 +259,14 @@
<key> <string>title</string> </key>
<value> <string>Graph</string> </value>
</item>
<item>
<key> <string>validator_field_id</string> </key>
<value> <string>my_core_mode_text_content_validator</string> </value>
</item>
<item>
<key> <string>validator_form_id</string> </key>
<value> <string>erp5_core/Base_viewFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -262,17 +286,4 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.getPortalObject().restrictedTraverse(\'dream_graph_editor/jsplumb/index.html\').absolute_url()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -12,6 +12,23 @@
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>jsplumb_graph</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
......@@ -44,6 +61,10 @@
<key> <string>id</string> </key>
<value> <string>validation_workflow</string> </value>
</item>
<item>
<key> <string>jsplumb_graph</string> </key>
<value> <string>{"class_definition":{},"graph":{"node":{"state_deleted":{"coordinate":{"top":0.949081048508587,"left":0.9496606334841629},"path":"/erp5/portal_workflow/validation_workflow/state_deleted","_class":"workflow.state","name":"Deleted","is_initial_state":false},"state_invalidated":{"coordinate":{"top":0.949081048508587,"left":0.5264423076923077},"path":"/erp5/portal_workflow/validation_workflow/state_invalidated","_class":"workflow.state","name":"Invalidated","is_initial_state":false},"state_validated":{"coordinate":{"top":0.1385959626393492,"left":0.3545673076923077},"path":"/erp5/portal_workflow/validation_workflow/state_validated","_class":"workflow.state","name":"Validated","is_initial_state":false},"state_draft":{"coordinate":{"top":0.41578788791804766,"left":0.025240384615384616},"path":"/erp5/portal_workflow/validation_workflow/state_draft","_class":"workflow.state","name":"Draft","is_initial_state":true}},"edge":{"transition_to_state_invalidated":{"source":"state_invalidated","destination":"state_invalidated","_class":"workflow.transition","name_path_dict":{"Delete Action":"/erp5/portal_workflow/validation_workflow/transition_delete_action","Validate Action":"/erp5/portal_workflow/validation_workflow/transition_validate_action"}},"state_draft_transition_validate":{"name":"Validate","description":"Validates a document in ERP5","destination":"state_validated","source":"state_draft","path":"/erp5/portal_workflow/validation_workflow/transition_validate","_class":"workflow.transition","transition_id":"transition_validate","actbox_url":null},"state_draft_transition_invalidate":{"name":"Invalidate","description":"This action invalidates a document in ERP5","destination":"state_invalidated","source":"state_draft","path":"/erp5/portal_workflow/validation_workflow/transition_invalidate","_class":"workflow.transition","transition_id":"transition_invalidate","actbox_url":null},"state_validated_transition_invalidate":{"name":"Invalidate","description":"This action invalidates a document in ERP5","destination":"state_invalidated","source":"state_validated","path":"/erp5/portal_workflow/validation_workflow/transition_invalidate","_class":"workflow.transition","transition_id":"transition_invalidate","actbox_url":null},"state_invalidated_transition_delete":{"name":"Delete","description":"Delete a document in ERP5","destination":"state_deleted","source":"state_invalidated","path":"/erp5/portal_workflow/validation_workflow/transition_delete","_class":"workflow.transition","transition_id":"transition_delete","actbox_url":null},"state_invalidated_transition_validate":{"name":"Validate","description":"Validates a document in ERP5","destination":"state_validated","source":"state_invalidated","path":"/erp5/portal_workflow/validation_workflow/transition_validate","_class":"workflow.transition","transition_id":"transition_validate","actbox_url":null},"transition_to_state_validated":{"source":"state_validated","destination":"state_validated","_class":"workflow.transition","name_path_dict":{"Invalidate Action":"/erp5/portal_workflow/validation_workflow/transition_invalidate_action"}},"state_draft_transition_delete":{"name":"Delete","description":"Delete a document in ERP5","destination":"state_deleted","source":"state_draft","path":"/erp5/portal_workflow/validation_workflow/transition_delete","_class":"workflow.transition","transition_id":"transition_delete","actbox_url":null},"transition_to_state_draft":{"source":"state_draft","destination":"state_draft","_class":"workflow.transition","name_path_dict":{"Invalidate Action":"/erp5/portal_workflow/validation_workflow/transition_invalidate_action","Delete Action":"/erp5/portal_workflow/validation_workflow/transition_delete_action","Validate Action":"/erp5/portal_workflow/validation_workflow/transition_validate_action"}}}}}</string> </value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
......
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