Rework start/stop api to use runtime-event notification message

This commit is contained in:
Nick O'Leary
2022-06-29 10:27:44 +01:00
parent 68c1e49f62
commit f33848e16b
11 changed files with 107 additions and 140 deletions

View File

@@ -169,6 +169,10 @@
}
},
"notification": {
"state": {
"flowsStopped": "Flows stopped",
"flowsStarted": "Flows started"
},
"warning": "<strong>Warning</strong>: __message__",
"warnings": {
"undeployedChanges": "node has undeployed changes",
@@ -291,12 +295,6 @@
"stopstart":{
"status": {
"state_changed": "Flows runtime has been changed to '__state__' state"
},
"errors": {
"notAllowed": "Method not allowed",
"notAuthorized": "Not authorized",
"notFound": "Not found",
"noResponse": "No response from server"
}
},
"deploy": {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
**/
/**
/**
* An Interface to nodes and utility functions for creating/adding/deleting nodes and links
* @namespace RED.nodes
*/

View File

@@ -336,7 +336,6 @@ var RED = (function() {
id: notificationId
}
if (notificationId === "runtime-state") {
RED.events.emit("runtime-state",msg);
if (msg.error === "safe-mode") {
options.buttons = [
{
@@ -477,9 +476,9 @@ var RED = (function() {
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
persistentNotifications[notificationId].close();
delete persistentNotifications[notificationId];
if (notificationId === 'runtime-state') {
RED.events.emit("runtime-state",msg);
}
}
if (notificationId === 'runtime-state') {
RED.events.emit("runtime-state",msg);
}
});
RED.comms.subscribe("status/#",function(topic,msg) {

View File

@@ -1,53 +1,36 @@
RED.runtime = (function() {
let state = ""
let settings = {ui: false, enabled: false};
const STOPPED = "stopped"
const STARTED = "started"
let settings = { ui: false, enabled: false };
const STOPPED = "stop"
const STARTED = "start"
const SAFE = "safe"
return {
init: function() {
// refresh the current runtime status from server
settings = Object.assign({}, settings, RED.settings.runtimeState);
RED.runtime.requestState()
// {id:"flows-run-state", started: false, state: "stopped", retain:true}
RED.comms.subscribe("notification/flows-run-state",function(topic,msg) {
RED.events.emit("flows-run-state",msg);
RED.runtime.updateState(msg.state);
});
},
get state() {
return state
},
get started() {
return state === STARTED
},
get states() {
return { STOPPED, STARTED }
},
updateState: function(newState) {
state = newState;
// disable pointer events on node buttons (e.g. inject/debug nodes)
$(".red-ui-flow-node-button").toggleClass("red-ui-flow-node-button-stopped", state === STOPPED)
// show/hide Start/Stop based on current state
if(settings.enabled === true && settings.ui === true) {
RED.menu.setVisible("deploymenu-item-runtime-stop", state === STARTED)
RED.menu.setVisible("deploymenu-item-runtime-start", state === STOPPED)
}
},
requestState: function(callback) {
$.ajax({
headers: {
"Accept":"application/json"
},
cache: false,
url: 'flows/state',
success: function(data) {
RED.runtime.updateState(data.state)
if(callback) {
callback(data.state)
RED.events.on("runtime-state", function(msg) {
if (msg.state) {
const currentState = state
state = msg.state
$(".red-ui-flow-node-button").toggleClass("red-ui-flow-node-button-stopped", state !== STARTED)
if(settings.enabled === true && settings.ui === true) {
RED.menu.setVisible("deploymenu-item-runtime-stop", state === STARTED)
RED.menu.setVisible("deploymenu-item-runtime-start", state !== STARTED)
}
// Do not notify the user about this event if:
// - This is the very first event we've received after loading the editor (currentState = '')
// - The state matches what we already thought was the case (state === currentState)
// - The event was triggered by a deploy (msg.deploy === true)
// - The event is a safe mode event - that gets notified separately
if (currentState !== '' && state !== currentState && !msg.deploy && state !== SAFE) {
RED.notify(RED._("notification.state.flows"+(state === STOPPED?'Stopped':'Started'), msg), "success")
}
}
});
},
get started() {
return state === STARTED
}
}
})()
})()

View File

@@ -69,7 +69,7 @@ RED.deploy = (function() {
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.svg",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}},
null
]
if(RED.settings.runtimeState && RED.settings.runtimeState.ui === true) {
if (RED.settings.runtimeState && RED.settings.runtimeState.ui === true) {
mainMenuItems.push({id:"deploymenu-item-runtime-start", icon:"red/images/start.svg",label:"Start"/*RED._("deploy.startFlows")*/,sublabel:"Start Flows" /*RED._("deploy.startFlowsDesc")*/,onselect:"core:start-flows", visible:false})
mainMenuItems.push({id:"deploymenu-item-runtime-stop", icon:"red/images/stop.svg",label:"Stop"/*RED._("deploy.startFlows")*/,sublabel:"Stop Flows" /*RED._("deploy.startFlowsDesc")*/,onselect:"core:stop-flows", visible:false})
}
@@ -302,7 +302,6 @@ RED.deploy = (function() {
deployInflight = true
deployButtonSetBusy()
shadeShow()
RED.runtime.updateState(state)
$.ajax({
url:"flows/state",
type: "POST",
@@ -311,30 +310,23 @@ RED.deploy = (function() {
if (deployWasEnabled) {
$("#red-ui-header-button-deploy").removeClass("disabled")
}
RED.runtime.updateState((data && data.state) || "unknown")
RED.notify(RED._("stopstart.status.state_changed", data), "success")
}).fail(function(xhr,textStatus,err) {
if (deployWasEnabled) {
$("#red-ui-header-button-deploy").removeClass("disabled")
}
if (xhr.status === 401) {
RED.notify(RED._("notification.error", { message: RED._("stopstart.errors.notAuthorized") }), "error")
} else if (xhr.status === 404) {
RED.notify(RED._("notification.error", { message: RED._("stopstart.errors.notFound") }), "error")
} else if (xhr.status === 405) {
RED.notify(RED._("notification.error", { message: RED._("stopstart.errors.notAllowed") }), "error")
RED.notify(RED._("notification.error", { message: RED._("user.notAuthorized") }), "error")
} else if (xhr.responseText) {
const errorDetail = { message: err ? (err + "") : "" }
try {
errorDetail.message = JSON.parse(xhr.responseText).message
} finally {
} finally {
errorDetail.message = errorDetail.message || xhr.responseText
}
RED.notify(RED._("notification.error", errorDetail), "error")
} else {
RED.notify(RED._("notification.error", { message: RED._("stopstart.errors.noResponse") }), "error")
RED.notify(RED._("notification.error", { message: RED._("deploy.errors.noResponse") }), "error")
}
RED.runtime.requestState()
}).always(function() {
const delta = Math.max(0, 300 - (Date.now() - startTime))
setTimeout(function () {
@@ -514,13 +506,10 @@ RED.deploy = (function() {
deployButtonSetBusy();
const data = { flows: nns };
data.runtimeState = RED.runtime.state;
if (data.runtimeState === RED.runtime.states.STOPPED || force) {
data._rev = RED.nodes.version();
} else {
if (!force) {
data.rev = RED.nodes.version();
}
deployInflight = true;
shadeShow();
$.ajax({

View File

@@ -4877,7 +4877,7 @@ RED.view = (function() {
if (d._def.button) {
var buttonEnabled = isButtonEnabled(d);
this.__buttonGroup__.classList.toggle("red-ui-flow-node-button-disabled", !buttonEnabled);
if(RED.runtime && Object.hasOwn(RED.runtime,'started')) {
if (RED.runtime && Object.hasOwn(RED.runtime,'started')) {
this.__buttonGroup__.classList.toggle("red-ui-flow-node-button-stopped", !RED.runtime.started);
}