Commit 539f7c8f authored by Thibaut Frain's avatar Thibaut Frain Committed by Jérome Perrin

Added save button to allow saving graph with jio

parent 2e471357
......@@ -7,6 +7,8 @@
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="mixin_promise.js" type="text/javascript"></script>
<script src="Input_viewProductionLine.js" type="text/javascript"></script>
</head>
<body>
......@@ -14,5 +16,9 @@
data-gadget-scope="productionline_toolbox"></div>
<div data-gadget-url="../jsplumb/index.html"
data-gadget-scope="productionline_graph"></div>
<form class="save_form">
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-edit ui-btn-icon-right">Save</button>
</form>
</body>
</html>
/*global window, rJS, RSVP */
(function (window, rJS, RSVP) {
/*global window, rJS, RSVP, loopEventListener*/
(function (window, rJS, RSVP, loopEventListener) {
"use strict";
var gadget_klass = rJS(window);
function saveGraph(evt) {
var gadget = this,
graph_data,
graph_gadget;
return new RSVP.Queue()
.push(function () {
// Prevent double click
evt.target.getElementsByClassName("ui-btn")[0].disabled = true;
return gadget.getDeclaredGadget("productionline_graph");
})
.push(function (graphgadget) {
graph_gadget = graphgadget;
return graph_gadget.getData();
})
.push(function (data) {
graph_data = data;
// Always get a fresh version, to prevent deleting spreadsheet & co
return gadget.aq_getAttachment({
"_id": gadget.props.jio_key,
"_attachment": "body.json"
});
})
.push(function (body) {
var data = JSON.parse(body);
data.nodes = JSON.parse(graph_data).nodes;
data.edges = JSON.parse(graph_data).edges;
data.preference = JSON.parse(graph_data).preference;
return gadget.aq_putAttachment({
"_id": gadget.props.jio_key,
"_attachment": "body.json",
"_data": JSON.stringify(data, null, 2),
"_mimetype": "application/json"
});
})
.push(function () {
evt.target.getElementsByClassName("ui-btn")[0].disabled = false;
});
}
function waitForSave(gadget) {
return loopEventListener(
gadget.props.element.getElementsByClassName("save_form")[0],
'submit',
false,
saveGraph.bind(gadget)
);
}
gadget_klass
.ready(function (g) {
......@@ -16,6 +65,7 @@
})
.declareAcquiredMethod("aq_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("aq_putAttachment", "jio_putAttachment")
.declareMethod("render", function (options) {
var jio_key = options.id, gadget = this;
......@@ -51,8 +101,9 @@
.push(function (toolbox) {
return RSVP.all([
graph.startService(),
toolbox.startService()
toolbox.startService(),
waitForSave(g)
]);
});
});
}(window, rJS, RSVP));
}(window, rJS, RSVP, loopEventListener));
......@@ -31,6 +31,51 @@
node_template = Handlebars.compile(node_template_source),
domParser = new DOMParser();
function loopJsplumbBind(gadget, type, callback) {
//////////////////////////
// Infinite event listener (promise is never resolved)
// eventListener is removed when promise is cancelled/rejected
//////////////////////////
var handle_event_callback,
callback_promise,
jsplumb_instance = gadget.props.jsplumb_instance;
function cancelResolver() {
if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) {
callback_promise.cancel();
}
}
function canceller() {
if (handle_event_callback !== undefined) {
jsplumb_instance.unbind(type);
}
cancelResolver();
}
function itsANonResolvableTrap(resolve, reject) {
handle_event_callback = function () {
var args = arguments;
cancelResolver();
callback_promise = new RSVP.Queue()
.push(function () {
return callback.apply(jsplumb_instance, args);
})
.push(undefined, function (error) {
if (!(error instanceof RSVP.CancellationError)) {
canceller();
reject(error);
}
});
};
jsplumb_instance.bind(type, handle_event_callback);
}
return new RSVP.Promise(itsANonResolvableTrap, canceller);
}
function getNodeId(node_container, element_id) {
var node_id;
$.each(node_container, function (k, v) {
......@@ -46,15 +91,15 @@
return node_container[node_id].element_id;
}
// function generateNodeId(node_container, element_type, option) {
// var n = 1;
// while (node_container[
// ((option.short_id || element_type) + n)
// ] !== undefined) {
// n += 1;
// }
// return (option.short_id || element_type) + n;
// }
function generateNodeId(gadget, element_type, option) {
var n = 1;
while (gadget.props.node_container[
((option.short_id || element_type) + n)
] !== undefined) {
n += 1;
}
return (option.short_id || element_type) + n;
}
function generateElementId(gadget_element) {
var n = 1;
......@@ -69,6 +114,36 @@
return undefined;
}
function updateConnectionData(gadget, connection, remove, edge_data) {
if (remove) {
delete gadget.props.edge_container[connection.id];
} else {
gadget.props.edge_container[connection.id] = [
getNodeId(gadget.props.node_container, connection.sourceId),
getNodeId(gadget.props.node_container, connection.targetId),
edge_data || {}
];
}
onDataChange();
}
// bind to connection/connectionDetached events,
// and update the list of connections on screen.
function waitForConnection(gadget) {
loopJsplumbBind(gadget, 'connection',
function (info, originalEvent) {
updateConnectionData(gadget, info.connection);
});
}
function waitForConnectionDetached(gadget) {
loopJsplumbBind(gadget, 'connectionDetached',
function (info, originalEvent) {
updateConnectionData(gadget, info.connection, true);
});
}
function convertToAbsolutePosition(gadget, x, y) {
var zoom_level = (gadget.props.preference_container.zoom_level || 1.0) *
1.1111,
......@@ -204,30 +279,7 @@
// return undefined;
// });
// split in 2 methods ? one for events one for manip
gadget.props.updateConnectionData
= function (connection, remove, edge_data) {
if (remove) {
delete gadget.props.edge_container[connection.id];
} else {
gadget.props.edge_container[connection.id] = [
getNodeId(gadget.props.node_container, connection.sourceId),
getNodeId(gadget.props.node_container, connection.targetId),
edge_data || {}
];
}
onDataChange();
};
// bind to connection/connectionDetached events,
// and update the list of connections on screen.
// jsplumb_instance
// .bind("connection", function (info, originalEvent) {
// gadget.props.updateConnectionData(info.connection);
// });
// jsplumb_instance
// .bind("connectionDetached", function (info, originalEvent) {
// gadget.props.updateConnectionData(info.connection, true);
// });
onDataChange();
draggable(gadget);
}
......@@ -423,13 +475,19 @@
// onDataChange();
// }
function newElement(gadget, element, option) {
element.name = element.name || option.name;
addElementToContainer(gadget.props.node_container, element);
var render_element = $(gadget.props.element).find("#main"),
function newElement(gadget, element, configuration) {
var element_type = element._class.replace('.', '-'),
option = configuration[element_type],
render_element = $(gadget.props.element).find("#main"),
coordinate = element.coordinate,
box,
absolute_position;
element.element_id = generateElementId(gadget.props.element);
if (!element.id) {
element.id = generateNodeId(gadget, element_type, option);
}
addElementToContainer(gadget.props.node_container, element);
element.name = element.name || option.name;
if (coordinate !== undefined) {
coordinate = updateElementCoordinate(
gadget,
......@@ -469,7 +527,7 @@
);
}
function waitForDrop(gadget) {
function waitForDrop(gadget, config) {
var target = gadget.props.element
.querySelector('#main'),
......@@ -504,7 +562,8 @@
},
"_class": element_class,
"name": element_class
});
},
config);
};
target.addEventListener('drop', callback, false);
......@@ -515,6 +574,9 @@
initGadgetMixin(gadget_klass);
gadget_klass
.declareAcquiredMethod('getConfigurationDict', 'getConfigurationDict')
.ready(function (g) {
g.props.node_container = {};
g.props.edge_container = {};
......@@ -544,34 +606,42 @@
var g = this,
preference = g.props.data.preference !== undefined ?
g.props.data.preference : {},
coordinates = preference.coordinates;
g.props.main = g.props.element.querySelector('#main');
initJsPlumb(g);
$.each(g.props.data.nodes, function (key, value) {
if (coordinates === undefined || coordinates[key] === undefined) {
value.coordinate = {
'top': 0.0,
'left': 0.0
};
} else {
value.coordinate = coordinates[key];
}
value.id = key;
newElement(g, value);
if (value.data) { // backward compatibility
updateElementData(g, key, {
data: value.data
coordinates = preference.coordinates,
config;
return g.getConfigurationDict()
.push(function (config_dict) {
config = config_dict;
g.props.main = g.props.element.querySelector('#main');
initJsPlumb(g);
$.each(g.props.data.nodes, function (key, value) {
if (coordinates === undefined || coordinates[key] === undefined) {
value.coordinate = {
'top': 0.0,
'left': 0.0
};
} else {
value.coordinate = coordinates[key];
}
value.id = key;
newElement(g, value, config);
if (value.data) { // backward compatibility
updateElementData(g, key, {
data: value.data
});
}
});
}
});
$.each(g.props.data.edges, function (key, value) {
addEdge(g, key, value);
});
return RSVP.all([
waitForDragover(g),
waitForDrop(g)
]);
$.each(g.props.data.edges, function (key, value) {
addEdge(g, key, value);
});
})
.push(function () {
return RSVP.all([
waitForDragover(g),
waitForDrop(g, config),
waitForConnection(g),
waitForConnectionDetached(g)
]);
});
});
}(RSVP, rJS, $, jsPlumb, Handlebars, initGadgetMixin,
loopEventListener, DOMParser));
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