diff --git a/editor/js/main.js b/editor/js/main.js
index a8af6f82c..b82d40387 100644
--- a/editor/js/main.js
+++ b/editor/js/main.js
@@ -83,6 +83,10 @@
RED.comms.subscribe("notification/#",function(topic,msg) {
var parts = topic.split("/");
var notificationId = parts[1];
+ if (notificationId === "runtime-deploy") {
+ // handled in ui/deploy.js
+ return;
+ }
if (msg.text) {
var text = RED._(msg.text,{default:msg.text});
if (!persistentNotifications.hasOwnProperty(notificationId)) {
diff --git a/editor/js/ui/deploy.js b/editor/js/ui/deploy.js
index d3e1feaf0..43800568f 100644
--- a/editor/js/ui/deploy.js
+++ b/editor/js/ui/deploy.js
@@ -30,6 +30,8 @@ RED.deploy = (function() {
var deploymentType = "full";
+ var deployInflight = false;
+
var currentDiff = null;
function changeDeploymentType(type) {
@@ -153,6 +155,7 @@ RED.deploy = (function() {
},
open: function() {
if ($( "#node-dialog-confirm-deploy-type" ).val() === "conflict") {
+ $( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.review'));
$("#node-dialog-confirm-deploy-deploy").hide();
$("#node-dialog-confirm-deploy-review").addClass('disabled').show();
$("#node-dialog-confirm-deploy-merge").addClass('disabled').show();
@@ -181,6 +184,7 @@ RED.deploy = (function() {
$("#node-dialog-confirm-deploy-hide").parent().hide();
} else {
+ $( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.confirm'));
$("#node-dialog-confirm-deploy-deploy").show();
$("#node-dialog-confirm-deploy-review").hide();
$("#node-dialog-confirm-deploy-merge").hide();
@@ -201,7 +205,33 @@ RED.deploy = (function() {
}
});
-
+ var activeNotifyMessage;
+ RED.comms.subscribe("notification/runtime-deploy",function(topic,msg) {
+ if (!activeNotifyMessage) {
+ var currentRev = RED.nodes.version();
+ if (currentRev === null || deployInflight || currentRev === msg.revision) {
+ return;
+ }
+ var message = $('
'+RED._('deploy.confirm.backgroundUpdate')+
+ '
'+
+ ''+
+ ''+
+ '
');
+ $(message.find('button')[0]).click(function(evt) {
+ evt.preventDefault();
+ activeNotifyMessage.close();
+ activeNotifyMessage = null;
+ })
+ $(message.find('button')[1]).click(function(evt) {
+ evt.preventDefault();
+ activeNotifyMessage.close();
+ var nns = RED.nodes.createCompleteNodeSet();
+ resolveConflict(nns);
+ activeNotifyMessage = null;
+ })
+ activeNotifyMessage = RED.notify(message,null,true);
+ }
+ });
}
function getNodeInfo(node) {
@@ -318,6 +348,7 @@ RED.deploy = (function() {
data.rev = RED.nodes.version();
}
+ deployInflight = true;
$.ajax({
url:"flows",
type: "POST",
@@ -372,6 +403,7 @@ RED.deploy = (function() {
RED.notify(RED._("deploy.deployFailed",{message:RED._("deploy.errors.noResponse")}),"error");
}
}).always(function() {
+ deployInflight = false;
var delta = Math.max(0,300-(Date.now()-startTime));
setTimeout(function() {
$(".deploy-button-content").css('opacity',1);
diff --git a/editor/js/ui/notifications.js b/editor/js/ui/notifications.js
index 7a0816e09..7c17741ea 100644
--- a/editor/js/ui/notifications.js
+++ b/editor/js/ui/notifications.js
@@ -36,7 +36,11 @@ RED.notify = (function() {
n.className = "notification notification-"+type;
}
n.style.display = "none";
- n.innerHTML = msg;
+ if (typeof msg === "string") {
+ n.innerHTML = msg;
+ } else {
+ $(n).append(msg);
+ }
$("#notifications").append(n);
$(n).slideDown(300);
n.close = (function() {
@@ -52,7 +56,11 @@ RED.notify = (function() {
n.update = (function() {
var nn = n;
return function(msg,timeout) {
- nn.innerHTML = msg;
+ if (typeof msg === "string") {
+ nn.innerHTML = msg;
+ } else {
+ $(nn).empty().append(msg);
+ }
if (timeout !== undefined && timeout > 0) {
window.clearTimeout(nn.timeoutid);
nn.timeoutid = window.setTimeout(nn.close,timeout);
diff --git a/red/api/locales/en-US/editor.json b/red/api/locales/en-US/editor.json
index 369589eb4..424a0e3c2 100644
--- a/red/api/locales/en-US/editor.json
+++ b/red/api/locales/en-US/editor.json
@@ -127,6 +127,7 @@
},
"confirm": {
"button": {
+ "ignore": "Ignore",
"confirm": "Confirm deploy",
"review": "Review differences",
"cancel": "Cancel",
@@ -137,6 +138,7 @@
"unknown": "The workspace contains some unknown node types:",
"confirm": "Are you sure you want to deploy?",
"conflict": "The server is running a more recent set of flows.",
+ "backgroundUpdate": "The flows on the server have been updated.",
"conflictChecking": "Checking to see if the changes can be merged automatically",
"conflictAutoMerge": "The changes include no conflicts and can be merged automatically.",
"conflictManualMerge": "The changes include conflicts that must be resolved before they can be deployed."
diff --git a/red/runtime/nodes/flows/index.js b/red/runtime/nodes/flows/index.js
index c52729cb8..dd1a2a489 100644
--- a/red/runtime/nodes/flows/index.js
+++ b/red/runtime/nodes/flows/index.js
@@ -135,10 +135,14 @@ function setFlows(_config,type,muteLog) {
if (started) {
return stop(type,diff,muteLog).then(function() {
context.clean(activeFlowConfig);
- start(type,diff,muteLog);
+ start(type,diff,muteLog).then(function() {
+ events.emit("runtime-event",{id:"runtime-deploy",revision:flowRevision});
+ });
return flowRevision;
}).otherwise(function(err) {
})
+ } else {
+ events.emit("runtime-event",{id:"runtime-deploy",revision:flowRevision});
}
});
}