@node-red/editor-client 4.0.0-beta.1 → 4.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/locales/de/editor.json +2 -0
- package/locales/en-US/editor.json +9 -1
- package/locales/fr/editor.json +17 -3
- package/locales/ja/editor.json +18 -4
- package/package.json +1 -1
- package/public/red/about +70 -0
- package/public/red/red.js +1602 -425
- package/public/red/red.min.js +3 -3
- package/public/red/style.min.css +2 -2
- package/public/red/tours/3.1/welcome.js +8 -8
- package/public/red/tours/images/nr4-background-deploy.png +0 -0
- package/public/red/tours/images/nr4-config-select.png +0 -0
- package/public/red/tours/images/nr4-diff-update.png +0 -0
- package/public/red/tours/images/nr4-multiplayer-location.png +0 -0
- package/public/red/tours/images/nr4-multiplayer.png +0 -0
- package/public/red/tours/images/nr4-plugins.png +0 -0
- package/public/red/tours/welcome.js +166 -11
- package/public/types/node/assert/strict.d.ts +1 -1
- package/public/types/node/assert.d.ts +8 -9
- package/public/types/node/async_hooks.d.ts +9 -5
- package/public/types/node/buffer.d.ts +43 -18
- package/public/types/node/child_process.d.ts +8 -5
- package/public/types/node/cluster.d.ts +15 -19
- package/public/types/node/console.d.ts +2 -2
- package/public/types/node/crypto.d.ts +165 -70
- package/public/types/node/dgram.d.ts +4 -4
- package/public/types/node/diagnostics_channel.d.ts +8 -7
- package/public/types/node/dns/promises.d.ts +11 -9
- package/public/types/node/dns.d.ts +18 -13
- package/public/types/node/dom-events.d.ts +129 -0
- package/public/types/node/domain.d.ts +2 -2
- package/public/types/node/events.d.ts +49 -12
- package/public/types/node/fs/promises.d.ts +68 -24
- package/public/types/node/fs.d.ts +132 -59
- package/public/types/node/globals.d.ts +31 -17
- package/public/types/node/http.d.ts +138 -27
- package/public/types/node/http2.d.ts +38 -5
- package/public/types/node/https.d.ts +12 -3
- package/public/types/node/module.d.ts +1 -2
- package/public/types/node/net.d.ts +69 -28
- package/public/types/node/os.d.ts +16 -5
- package/public/types/node/path.d.ts +5 -5
- package/public/types/node/perf_hooks.d.ts +48 -9
- package/public/types/node/process.d.ts +18 -17
- package/public/types/node/querystring.d.ts +2 -2
- package/public/types/node/readline/promises.d.ts +146 -0
- package/public/types/node/readline.d.ts +141 -31
- package/public/types/node/stream/consumers.d.ts +2 -2
- package/public/types/node/stream/promises.d.ts +1 -1
- package/public/types/node/stream/web.d.ts +4 -66
- package/public/types/node/stream.d.ts +96 -118
- package/public/types/node/string_decoder.d.ts +2 -2
- package/public/types/node/test.d.ts +200 -16
- package/public/types/node/timers/promises.d.ts +1 -26
- package/public/types/node/timers.d.ts +2 -2
- package/public/types/node/tls.d.ts +21 -12
- package/public/types/node/trace_events.d.ts +12 -2
- package/public/types/node/ts4.8/assert/strict.d.ts +11 -0
- package/public/types/node/ts4.8/assert.d.ts +964 -0
- package/public/types/node/ts4.8/async_hooks.d.ts +504 -0
- package/public/types/node/ts4.8/buffer.d.ts +2262 -0
- package/public/types/node/ts4.8/child_process.d.ts +1372 -0
- package/public/types/node/ts4.8/cluster.d.ts +413 -0
- package/public/types/node/ts4.8/console.d.ts +415 -0
- package/public/types/node/ts4.8/crypto.d.ts +3967 -0
- package/public/types/node/ts4.8/dgram.d.ts +548 -0
- package/public/types/node/ts4.8/diagnostics_channel.d.ts +156 -0
- package/public/types/node/ts4.8/dns/promises.d.ts +373 -0
- package/public/types/node/ts4.8/dns.d.ts +662 -0
- package/public/types/node/ts4.8/dom-events.d.ts +129 -0
- package/public/types/node/ts4.8/domain.d.ts +173 -0
- package/public/types/node/ts4.8/events.d.ts +681 -0
- package/public/types/node/ts4.8/fs/promises.d.ts +1141 -0
- package/public/types/node/ts4.8/fs.d.ts +3875 -0
- package/public/types/node/ts4.8/globals.d.ts +297 -0
- package/public/types/node/ts4.8/http.d.ts +1617 -0
- package/public/types/node/ts4.8/http2.d.ts +2137 -0
- package/public/types/node/ts4.8/https.d.ts +544 -0
- package/public/types/node/ts4.8/module.d.ts +117 -0
- package/public/types/node/ts4.8/net.d.ts +872 -0
- package/public/types/node/ts4.8/os.d.ts +469 -0
- package/public/types/node/ts4.8/path.d.ts +194 -0
- package/public/types/node/ts4.8/perf_hooks.d.ts +628 -0
- package/public/types/node/ts4.8/process.d.ts +1485 -0
- package/public/types/node/ts4.8/querystring.d.ts +134 -0
- package/public/types/node/ts4.8/readline/promises.d.ts +146 -0
- package/public/types/node/ts4.8/readline.d.ts +656 -0
- package/public/types/node/ts4.8/stream/consumers.d.ts +15 -0
- package/public/types/node/ts4.8/stream/promises.d.ts +45 -0
- package/public/types/node/ts4.8/stream/web.d.ts +333 -0
- package/public/types/node/ts4.8/stream.d.ts +1343 -0
- package/public/types/node/ts4.8/string_decoder.d.ts +70 -0
- package/public/types/node/ts4.8/test.d.ts +377 -0
- package/public/types/node/ts4.8/timers/promises.d.ts +71 -0
- package/public/types/node/ts4.8/timers.d.ts +97 -0
- package/public/types/node/ts4.8/tls.d.ts +1031 -0
- package/public/types/node/ts4.8/trace_events.d.ts +174 -0
- package/public/types/node/ts4.8/tty.d.ts +209 -0
- package/public/types/node/ts4.8/url.d.ts +900 -0
- package/public/types/node/ts4.8/util.d.ts +1853 -0
- package/public/types/node/ts4.8/v8.d.ts +399 -0
- package/public/types/node/ts4.8/vm.d.ts +512 -0
- package/public/types/node/ts4.8/wasi.d.ts +161 -0
- package/public/types/node/ts4.8/worker_threads.d.ts +692 -0
- package/public/types/node/ts4.8/zlib.d.ts +520 -0
- package/public/types/node/tty.d.ts +5 -3
- package/public/types/node/url.d.ts +81 -39
- package/public/types/node/util.d.ts +269 -13
- package/public/types/node/v8.d.ts +22 -4
- package/public/types/node/vm.d.ts +7 -5
- package/public/types/node/wasi.d.ts +2 -2
- package/public/types/node/worker_threads.d.ts +51 -11
- package/public/types/node/zlib.d.ts +2 -2
- package/public/types/node-red/func.d.ts +26 -17
- package/public/types/node-red/util.d.ts +1 -1
- package/public/vendor/ace/worker-jsonata.js +1 -1
- package/public/vendor/monaco/dist/{fa2cc0ab9f0bec2b3365.ttf → 0c718f5b7d2bce997c5f.ttf} +0 -0
- package/public/vendor/monaco/dist/css.worker.js +1 -1
- package/public/vendor/monaco/dist/css.worker.js.LICENSE.txt +1 -1
- package/public/vendor/monaco/dist/editor.js +1 -29
- package/public/vendor/monaco/dist/editor.js.LICENSE.txt +2 -2
- package/public/vendor/monaco/dist/editor.worker.js +1 -1
- package/public/vendor/monaco/dist/html.worker.js +1 -1
- package/public/vendor/monaco/dist/html.worker.js.LICENSE.txt +1 -1
- package/public/vendor/monaco/dist/json.worker.js +1 -1
- package/public/vendor/monaco/dist/json.worker.js.LICENSE.txt +1 -1
- package/public/vendor/monaco/dist/locale/cs.js +324 -106
- package/public/vendor/monaco/dist/locale/de.js +336 -118
- package/public/vendor/monaco/dist/locale/es.js +329 -111
- package/public/vendor/monaco/dist/locale/fr.js +334 -116
- package/public/vendor/monaco/dist/locale/it.js +327 -109
- package/public/vendor/monaco/dist/locale/ja.js +329 -111
- package/public/vendor/monaco/dist/locale/ko.js +330 -112
- package/public/vendor/monaco/dist/locale/pl.js +329 -111
- package/public/vendor/monaco/dist/locale/pt-br.js +329 -111
- package/public/vendor/monaco/dist/locale/qps-ploc.js +330 -112
- package/public/vendor/monaco/dist/locale/ru.js +331 -113
- package/public/vendor/monaco/dist/locale/tr.js +329 -111
- package/public/vendor/monaco/dist/locale/zh-hans.js +331 -113
- package/public/vendor/monaco/dist/locale/zh-hant.js +331 -113
- package/public/vendor/monaco/dist/ts.worker.js +2 -2
- package/public/vendor/vendor.js +1 -1
- package/public/vendor/monaco/dist/7064e66c3890a12c47b4.ttf +0 -0
package/public/red/red.js
CHANGED
|
@@ -116,6 +116,7 @@ var RED = (function() {
|
|
|
116
116
|
cache: false,
|
|
117
117
|
url: 'plugins',
|
|
118
118
|
success: function(data) {
|
|
119
|
+
RED.plugins.setPluginList(data);
|
|
119
120
|
loader.reportProgress(RED._("event.loadPlugins"), 13)
|
|
120
121
|
RED.i18n.loadPluginCatalogs(function() {
|
|
121
122
|
loadPlugins(function() {
|
|
@@ -388,6 +389,7 @@ var RED = (function() {
|
|
|
388
389
|
RED.workspaces.show(workspaces[0]);
|
|
389
390
|
}
|
|
390
391
|
}
|
|
392
|
+
RED.events.emit('flows:loaded')
|
|
391
393
|
} catch(err) {
|
|
392
394
|
console.warn(err);
|
|
393
395
|
RED.notify(
|
|
@@ -625,6 +627,41 @@ var RED = (function() {
|
|
|
625
627
|
RED.view.redrawStatus(node);
|
|
626
628
|
}
|
|
627
629
|
});
|
|
630
|
+
RED.comms.subscribe("notification/plugin/#",function(topic,msg) {
|
|
631
|
+
if (topic == "notification/plugin/added") {
|
|
632
|
+
RED.settings.refreshSettings(function(err, data) {
|
|
633
|
+
let addedPlugins = [];
|
|
634
|
+
msg.forEach(function(m) {
|
|
635
|
+
let id = m.id;
|
|
636
|
+
RED.plugins.addPlugin(m);
|
|
637
|
+
|
|
638
|
+
m.plugins.forEach((p) => {
|
|
639
|
+
addedPlugins.push(p.id);
|
|
640
|
+
})
|
|
641
|
+
|
|
642
|
+
RED.i18n.loadNodeCatalog(id, function() {
|
|
643
|
+
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
|
|
644
|
+
$.ajax({
|
|
645
|
+
headers: {
|
|
646
|
+
"Accept":"text/html",
|
|
647
|
+
"Accept-Language": lang
|
|
648
|
+
},
|
|
649
|
+
cache: false,
|
|
650
|
+
url: 'plugins/'+id,
|
|
651
|
+
success: function(data) {
|
|
652
|
+
appendPluginConfig(data);
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
});
|
|
657
|
+
if (addedPlugins.length) {
|
|
658
|
+
let pluginList = "<ul><li>"+addedPlugins.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
|
|
659
|
+
// ToDo: Adapt notification (node -> plugin)
|
|
660
|
+
RED.notify(RED._("palette.event.nodeAdded", {count:addedPlugins.length})+pluginList,"success");
|
|
661
|
+
}
|
|
662
|
+
})
|
|
663
|
+
}
|
|
664
|
+
});
|
|
628
665
|
|
|
629
666
|
let pendingNodeRemovedNotifications = []
|
|
630
667
|
let pendingNodeRemovedTimeout
|
|
@@ -894,6 +931,10 @@ var RED = (function() {
|
|
|
894
931
|
|
|
895
932
|
RED.nodes.init();
|
|
896
933
|
RED.runtime.init()
|
|
934
|
+
|
|
935
|
+
if (RED.settings.theme("multiplayer.enabled",false)) {
|
|
936
|
+
RED.multiplayer.init()
|
|
937
|
+
}
|
|
897
938
|
RED.comms.connect();
|
|
898
939
|
|
|
899
940
|
$("#red-ui-main-container").show();
|
|
@@ -1812,6 +1853,7 @@ RED.user = (function() {
|
|
|
1812
1853
|
}
|
|
1813
1854
|
|
|
1814
1855
|
function logout() {
|
|
1856
|
+
RED.events.emit('logout')
|
|
1815
1857
|
var tokens = RED.settings.get("auth-tokens");
|
|
1816
1858
|
var token = tokens?tokens.access_token:"";
|
|
1817
1859
|
$.ajax({
|
|
@@ -1836,6 +1878,8 @@ RED.user = (function() {
|
|
|
1836
1878
|
|
|
1837
1879
|
function updateUserMenu() {
|
|
1838
1880
|
$("#red-ui-header-button-user-submenu li").remove();
|
|
1881
|
+
const userMenu = $("#red-ui-header-button-user")
|
|
1882
|
+
userMenu.empty()
|
|
1839
1883
|
if (RED.settings.user.anonymous) {
|
|
1840
1884
|
RED.menu.addItem("red-ui-header-button-user",{
|
|
1841
1885
|
id:"usermenu-item-login",
|
|
@@ -1863,7 +1907,8 @@ RED.user = (function() {
|
|
|
1863
1907
|
}
|
|
1864
1908
|
});
|
|
1865
1909
|
}
|
|
1866
|
-
|
|
1910
|
+
const userIcon = generateUserIcon(RED.settings.user)
|
|
1911
|
+
userIcon.appendTo(userMenu);
|
|
1867
1912
|
}
|
|
1868
1913
|
|
|
1869
1914
|
function init() {
|
|
@@ -1872,14 +1917,6 @@ RED.user = (function() {
|
|
|
1872
1917
|
|
|
1873
1918
|
var userMenu = $('<li><a id="red-ui-header-button-user" class="button hide" href="#"></a></li>')
|
|
1874
1919
|
.prependTo(".red-ui-header-toolbar");
|
|
1875
|
-
if (RED.settings.user.image) {
|
|
1876
|
-
$('<span class="user-profile"></span>').css({
|
|
1877
|
-
backgroundImage: "url("+RED.settings.user.image+")",
|
|
1878
|
-
}).appendTo(userMenu.find("a"));
|
|
1879
|
-
} else {
|
|
1880
|
-
$('<i class="fa fa-user"></i>').appendTo(userMenu.find("a"));
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
1920
|
RED.menu.init({id:"red-ui-header-button-user",
|
|
1884
1921
|
options: []
|
|
1885
1922
|
});
|
|
@@ -1942,12 +1979,30 @@ RED.user = (function() {
|
|
|
1942
1979
|
return false;
|
|
1943
1980
|
}
|
|
1944
1981
|
|
|
1982
|
+
function generateUserIcon(user) {
|
|
1983
|
+
const userIcon = $('<span class="red-ui-user-profile"></span>')
|
|
1984
|
+
if (user.image) {
|
|
1985
|
+
userIcon.addClass('has_profile_image')
|
|
1986
|
+
userIcon.css({
|
|
1987
|
+
backgroundImage: "url("+user.image+")",
|
|
1988
|
+
})
|
|
1989
|
+
} else if (user.anonymous) {
|
|
1990
|
+
$('<i class="fa fa-user"></i>').appendTo(userIcon);
|
|
1991
|
+
} else {
|
|
1992
|
+
$('<span>').text(user.username.substring(0,2)).appendTo(userIcon);
|
|
1993
|
+
}
|
|
1994
|
+
if (user.profileColor !== undefined) {
|
|
1995
|
+
userIcon.addClass('red-ui-user-profile-color-' + user.profileColor)
|
|
1996
|
+
}
|
|
1997
|
+
return userIcon
|
|
1998
|
+
}
|
|
1945
1999
|
|
|
1946
2000
|
return {
|
|
1947
2001
|
init: init,
|
|
1948
2002
|
login: login,
|
|
1949
2003
|
logout: logout,
|
|
1950
|
-
hasPermission: hasPermission
|
|
2004
|
+
hasPermission: hasPermission,
|
|
2005
|
+
generateUserIcon
|
|
1951
2006
|
}
|
|
1952
2007
|
|
|
1953
2008
|
})();
|
|
@@ -1979,6 +2034,15 @@ RED.comms = (function() {
|
|
|
1979
2034
|
var reconnectAttempts = 0;
|
|
1980
2035
|
var active = false;
|
|
1981
2036
|
|
|
2037
|
+
RED.events.on('login', function(username) {
|
|
2038
|
+
// User has logged in
|
|
2039
|
+
// Need to upgrade the connection to be authenticated
|
|
2040
|
+
if (ws && ws.readyState == 1) {
|
|
2041
|
+
const auth_tokens = RED.settings.get("auth-tokens");
|
|
2042
|
+
ws.send(JSON.stringify({auth:auth_tokens.access_token}))
|
|
2043
|
+
}
|
|
2044
|
+
})
|
|
2045
|
+
|
|
1982
2046
|
function connectWS() {
|
|
1983
2047
|
active = true;
|
|
1984
2048
|
var wspath;
|
|
@@ -2009,6 +2073,7 @@ RED.comms = (function() {
|
|
|
2009
2073
|
ws.send(JSON.stringify({subscribe:t}));
|
|
2010
2074
|
}
|
|
2011
2075
|
}
|
|
2076
|
+
emit('connect')
|
|
2012
2077
|
}
|
|
2013
2078
|
|
|
2014
2079
|
ws = new WebSocket(wspath);
|
|
@@ -2133,10 +2198,54 @@ RED.comms = (function() {
|
|
|
2133
2198
|
}
|
|
2134
2199
|
}
|
|
2135
2200
|
|
|
2201
|
+
function send(topic, msg) {
|
|
2202
|
+
if (ws && ws.readyState == 1) {
|
|
2203
|
+
ws.send(JSON.stringify({
|
|
2204
|
+
topic,
|
|
2205
|
+
data: msg
|
|
2206
|
+
}))
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
const eventHandlers = {};
|
|
2211
|
+
function on(evt,func) {
|
|
2212
|
+
eventHandlers[evt] = eventHandlers[evt]||[];
|
|
2213
|
+
eventHandlers[evt].push(func);
|
|
2214
|
+
}
|
|
2215
|
+
function off(evt,func) {
|
|
2216
|
+
const handler = eventHandlers[evt];
|
|
2217
|
+
if (handler) {
|
|
2218
|
+
for (let i=0;i<handler.length;i++) {
|
|
2219
|
+
if (handler[i] === func) {
|
|
2220
|
+
handler.splice(i,1);
|
|
2221
|
+
return;
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
function emit() {
|
|
2227
|
+
const evt = arguments[0]
|
|
2228
|
+
const args = Array.prototype.slice.call(arguments,1);
|
|
2229
|
+
if (eventHandlers[evt]) {
|
|
2230
|
+
let cpyHandlers = [...eventHandlers[evt]];
|
|
2231
|
+
for (let i=0;i<cpyHandlers.length;i++) {
|
|
2232
|
+
try {
|
|
2233
|
+
cpyHandlers[i].apply(null, args);
|
|
2234
|
+
} catch(err) {
|
|
2235
|
+
console.warn("RED.comms.emit error: ["+evt+"] "+(err.toString()));
|
|
2236
|
+
console.warn(err);
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2136
2242
|
return {
|
|
2137
2243
|
connect: connectWS,
|
|
2138
2244
|
subscribe: subscribe,
|
|
2139
|
-
unsubscribe:unsubscribe
|
|
2245
|
+
unsubscribe:unsubscribe,
|
|
2246
|
+
on,
|
|
2247
|
+
off,
|
|
2248
|
+
send
|
|
2140
2249
|
}
|
|
2141
2250
|
})();
|
|
2142
2251
|
;RED.runtime = (function() {
|
|
@@ -2175,6 +2284,496 @@ RED.comms = (function() {
|
|
|
2175
2284
|
}
|
|
2176
2285
|
}
|
|
2177
2286
|
})()
|
|
2287
|
+
;RED.multiplayer = (function () {
|
|
2288
|
+
|
|
2289
|
+
// activeSessionId - used to identify sessions across websocket reconnects
|
|
2290
|
+
let activeSessionId
|
|
2291
|
+
|
|
2292
|
+
let headerWidget
|
|
2293
|
+
// Map of session id to { session:'', user:{}, location:{}}
|
|
2294
|
+
let sessions = {}
|
|
2295
|
+
// Map of username to { user:{}, sessions:[] }
|
|
2296
|
+
let users = {}
|
|
2297
|
+
|
|
2298
|
+
function addUserSession (session) {
|
|
2299
|
+
if (sessions[session.session]) {
|
|
2300
|
+
// This is an existing connection that has been authenticated
|
|
2301
|
+
const existingSession = sessions[session.session]
|
|
2302
|
+
if (existingSession.user.username !== session.user.username) {
|
|
2303
|
+
removeUserHeaderButton(users[existingSession.user.username])
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
sessions[session.session] = session
|
|
2307
|
+
const user = users[session.user.username] = users[session.user.username] || {
|
|
2308
|
+
user: session.user,
|
|
2309
|
+
sessions: []
|
|
2310
|
+
}
|
|
2311
|
+
if (session.user.profileColor === undefined) {
|
|
2312
|
+
session.user.profileColor = (1 + Math.floor(Math.random() * 5))
|
|
2313
|
+
}
|
|
2314
|
+
session.location = session.location || {}
|
|
2315
|
+
user.sessions.push(session)
|
|
2316
|
+
|
|
2317
|
+
if (session.session === activeSessionId) {
|
|
2318
|
+
// This is the current user session - do not add a extra button for them
|
|
2319
|
+
} else {
|
|
2320
|
+
if (user.sessions.length === 1) {
|
|
2321
|
+
if (user.button) {
|
|
2322
|
+
clearTimeout(user.inactiveTimeout)
|
|
2323
|
+
clearTimeout(user.removeTimeout)
|
|
2324
|
+
user.button.removeClass('inactive')
|
|
2325
|
+
} else {
|
|
2326
|
+
addUserHeaderButton(user)
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
sessions[session.session].location = session.location
|
|
2330
|
+
updateUserLocation(session.session)
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
function removeUserSession (sessionId, isDisconnected) {
|
|
2335
|
+
removeUserLocation(sessionId)
|
|
2336
|
+
const session = sessions[sessionId]
|
|
2337
|
+
delete sessions[sessionId]
|
|
2338
|
+
const user = users[session.user.username]
|
|
2339
|
+
const i = user.sessions.indexOf(session)
|
|
2340
|
+
user.sessions.splice(i, 1)
|
|
2341
|
+
if (isDisconnected) {
|
|
2342
|
+
removeUserHeaderButton(user)
|
|
2343
|
+
} else {
|
|
2344
|
+
if (user.sessions.length === 0) {
|
|
2345
|
+
// Give the user 5s to reconnect before marking inactive
|
|
2346
|
+
user.inactiveTimeout = setTimeout(() => {
|
|
2347
|
+
user.button.addClass('inactive')
|
|
2348
|
+
// Give the user further 20 seconds to reconnect before removing them
|
|
2349
|
+
// from the user toolbar entirely
|
|
2350
|
+
user.removeTimeout = setTimeout(() => {
|
|
2351
|
+
removeUserHeaderButton(user)
|
|
2352
|
+
}, 20000)
|
|
2353
|
+
}, 5000)
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
function addUserHeaderButton (user) {
|
|
2359
|
+
user.button = $('<li class="red-ui-multiplayer-user"><button type="button" class="red-ui-multiplayer-user-icon"></button></li>')
|
|
2360
|
+
.attr('data-username', user.user.username)
|
|
2361
|
+
.prependTo("#red-ui-multiplayer-user-list");
|
|
2362
|
+
var button = user.button.find("button")
|
|
2363
|
+
RED.popover.tooltip(button, user.user.username)
|
|
2364
|
+
button.on('click', function () {
|
|
2365
|
+
const location = user.sessions[0].location
|
|
2366
|
+
revealUser(location)
|
|
2367
|
+
})
|
|
2368
|
+
|
|
2369
|
+
const userProfile = RED.user.generateUserIcon(user.user)
|
|
2370
|
+
userProfile.appendTo(button)
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
function removeUserHeaderButton (user) {
|
|
2374
|
+
user.button.remove()
|
|
2375
|
+
delete user.button
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
function getLocation () {
|
|
2379
|
+
const location = {
|
|
2380
|
+
workspace: RED.workspaces.active()
|
|
2381
|
+
}
|
|
2382
|
+
const editStack = RED.editor.getEditStack()
|
|
2383
|
+
for (let i = editStack.length - 1; i >= 0; i--) {
|
|
2384
|
+
if (editStack[i].id) {
|
|
2385
|
+
location.node = editStack[i].id
|
|
2386
|
+
break
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
return location
|
|
2390
|
+
}
|
|
2391
|
+
function publishLocation () {
|
|
2392
|
+
const location = getLocation()
|
|
2393
|
+
if (location.workspace !== 0) {
|
|
2394
|
+
log('send', 'multiplayer/location', location)
|
|
2395
|
+
RED.comms.send('multiplayer/location', location)
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
function revealUser(location, skipWorkspace) {
|
|
2400
|
+
if (location.node) {
|
|
2401
|
+
// Need to check if this is a known node, so we can fall back to revealing
|
|
2402
|
+
// the workspace instead
|
|
2403
|
+
const node = RED.nodes.node(location.node)
|
|
2404
|
+
if (node) {
|
|
2405
|
+
RED.view.reveal(location.node)
|
|
2406
|
+
} else if (!skipWorkspace && location.workspace) {
|
|
2407
|
+
RED.view.reveal(location.workspace)
|
|
2408
|
+
}
|
|
2409
|
+
} else if (!skipWorkspace && location.workspace) {
|
|
2410
|
+
RED.view.reveal(location.workspace)
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
const workspaceTrays = {}
|
|
2415
|
+
function getWorkspaceTray(workspaceId) {
|
|
2416
|
+
// console.log('get tray for',workspaceId)
|
|
2417
|
+
if (!workspaceTrays[workspaceId]) {
|
|
2418
|
+
const tray = $('<div class="red-ui-multiplayer-users-tray"></div>')
|
|
2419
|
+
const users = []
|
|
2420
|
+
const userIcons = {}
|
|
2421
|
+
|
|
2422
|
+
const userCountIcon = $(`<div class="red-ui-multiplayer-user-location"><span class="red-ui-user-profile red-ui-multiplayer-user-count"><span></span></span></div>`)
|
|
2423
|
+
const userCountSpan = userCountIcon.find('span span')
|
|
2424
|
+
userCountIcon.hide()
|
|
2425
|
+
userCountSpan.text('')
|
|
2426
|
+
userCountIcon.appendTo(tray)
|
|
2427
|
+
const userCountTooltip = RED.popover.tooltip(userCountIcon, function () {
|
|
2428
|
+
const content = $('<div>')
|
|
2429
|
+
users.forEach(sessionId => {
|
|
2430
|
+
$('<div>').append($('<a href="#">').text(sessions[sessionId].user.username).on('click', function (evt) {
|
|
2431
|
+
evt.preventDefault()
|
|
2432
|
+
revealUser(sessions[sessionId].location, true)
|
|
2433
|
+
userCountTooltip.close()
|
|
2434
|
+
})).appendTo(content)
|
|
2435
|
+
})
|
|
2436
|
+
return content
|
|
2437
|
+
},
|
|
2438
|
+
null,
|
|
2439
|
+
true
|
|
2440
|
+
)
|
|
2441
|
+
|
|
2442
|
+
const updateUserCount = function () {
|
|
2443
|
+
const maxShown = 2
|
|
2444
|
+
const children = tray.children()
|
|
2445
|
+
children.each(function (index, element) {
|
|
2446
|
+
const i = users.length - index
|
|
2447
|
+
if (i > maxShown) {
|
|
2448
|
+
$(this).hide()
|
|
2449
|
+
} else if (i >= 0) {
|
|
2450
|
+
$(this).show()
|
|
2451
|
+
}
|
|
2452
|
+
})
|
|
2453
|
+
if (users.length < maxShown + 1) {
|
|
2454
|
+
userCountIcon.hide()
|
|
2455
|
+
} else {
|
|
2456
|
+
userCountSpan.text('+'+(users.length - maxShown))
|
|
2457
|
+
userCountIcon.show()
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
workspaceTrays[workspaceId] = {
|
|
2461
|
+
attached: false,
|
|
2462
|
+
tray,
|
|
2463
|
+
users,
|
|
2464
|
+
userIcons,
|
|
2465
|
+
addUser: function (sessionId) {
|
|
2466
|
+
if (users.indexOf(sessionId) === -1) {
|
|
2467
|
+
// console.log(`addUser ws:${workspaceId} session:${sessionId}`)
|
|
2468
|
+
users.push(sessionId)
|
|
2469
|
+
const userLocationId = `red-ui-multiplayer-user-location-${sessionId}`
|
|
2470
|
+
const userLocationIcon = $(`<div class="red-ui-multiplayer-user-location" id="${userLocationId}"></div>`)
|
|
2471
|
+
RED.user.generateUserIcon(sessions[sessionId].user).appendTo(userLocationIcon)
|
|
2472
|
+
userLocationIcon.prependTo(tray)
|
|
2473
|
+
RED.popover.tooltip(userLocationIcon, sessions[sessionId].user.username)
|
|
2474
|
+
userIcons[sessionId] = userLocationIcon
|
|
2475
|
+
updateUserCount()
|
|
2476
|
+
}
|
|
2477
|
+
},
|
|
2478
|
+
removeUser: function (sessionId) {
|
|
2479
|
+
// console.log(`removeUser ws:${workspaceId} session:${sessionId}`)
|
|
2480
|
+
const userLocationId = `red-ui-multiplayer-user-location-${sessionId}`
|
|
2481
|
+
const index = users.indexOf(sessionId)
|
|
2482
|
+
if (index > -1) {
|
|
2483
|
+
users.splice(index, 1)
|
|
2484
|
+
userIcons[sessionId].remove()
|
|
2485
|
+
delete userIcons[sessionId]
|
|
2486
|
+
}
|
|
2487
|
+
updateUserCount()
|
|
2488
|
+
},
|
|
2489
|
+
updateUserCount
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
const trayDef = workspaceTrays[workspaceId]
|
|
2493
|
+
if (!trayDef.attached) {
|
|
2494
|
+
const workspaceTab = $(`#red-ui-tab-${workspaceId}`)
|
|
2495
|
+
if (workspaceTab.length > 0) {
|
|
2496
|
+
trayDef.attached = true
|
|
2497
|
+
trayDef.tray.appendTo(workspaceTab)
|
|
2498
|
+
trayDef.users.forEach(sessionId => {
|
|
2499
|
+
trayDef.userIcons[sessionId].on('click', function (evt) {
|
|
2500
|
+
revealUser(sessions[sessionId].location, true)
|
|
2501
|
+
})
|
|
2502
|
+
})
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
return workspaceTrays[workspaceId]
|
|
2506
|
+
}
|
|
2507
|
+
function attachWorkspaceTrays () {
|
|
2508
|
+
let viewTouched = false
|
|
2509
|
+
for (let sessionId of Object.keys(sessions)) {
|
|
2510
|
+
const location = sessions[sessionId].location
|
|
2511
|
+
if (location) {
|
|
2512
|
+
if (location.workspace) {
|
|
2513
|
+
getWorkspaceTray(location.workspace).updateUserCount()
|
|
2514
|
+
}
|
|
2515
|
+
if (location.node) {
|
|
2516
|
+
addUserToNode(sessionId, location.node)
|
|
2517
|
+
viewTouched = true
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
if (viewTouched) {
|
|
2522
|
+
RED.view.redraw()
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
|
|
2526
|
+
function addUserToNode(sessionId, nodeId) {
|
|
2527
|
+
const node = RED.nodes.node(nodeId)
|
|
2528
|
+
if (node) {
|
|
2529
|
+
if (!node._multiplayer) {
|
|
2530
|
+
node._multiplayer = {
|
|
2531
|
+
users: [sessionId]
|
|
2532
|
+
}
|
|
2533
|
+
node._multiplayer_refresh = true
|
|
2534
|
+
} else {
|
|
2535
|
+
if (node._multiplayer.users.indexOf(sessionId) === -1) {
|
|
2536
|
+
node._multiplayer.users.push(sessionId)
|
|
2537
|
+
node._multiplayer_refresh = true
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
function removeUserFromNode(sessionId, nodeId) {
|
|
2543
|
+
const node = RED.nodes.node(nodeId)
|
|
2544
|
+
if (node && node._multiplayer) {
|
|
2545
|
+
const i = node._multiplayer.users.indexOf(sessionId)
|
|
2546
|
+
if (i > -1) {
|
|
2547
|
+
node._multiplayer.users.splice(i, 1)
|
|
2548
|
+
}
|
|
2549
|
+
if (node._multiplayer.users.length === 0) {
|
|
2550
|
+
delete node._multiplayer
|
|
2551
|
+
} else {
|
|
2552
|
+
node._multiplayer_refresh = true
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
function removeUserLocation (sessionId) {
|
|
2559
|
+
updateUserLocation(sessionId, {})
|
|
2560
|
+
}
|
|
2561
|
+
function updateUserLocation (sessionId, location) {
|
|
2562
|
+
let viewTouched = false
|
|
2563
|
+
const oldLocation = sessions[sessionId].location
|
|
2564
|
+
if (location) {
|
|
2565
|
+
if (oldLocation.workspace !== location.workspace) {
|
|
2566
|
+
// console.log('removing', sessionId, oldLocation.workspace)
|
|
2567
|
+
workspaceTrays[oldLocation.workspace]?.removeUser(sessionId)
|
|
2568
|
+
}
|
|
2569
|
+
if (oldLocation.node !== location.node) {
|
|
2570
|
+
removeUserFromNode(sessionId, oldLocation.node)
|
|
2571
|
+
viewTouched = true
|
|
2572
|
+
}
|
|
2573
|
+
sessions[sessionId].location = location
|
|
2574
|
+
} else {
|
|
2575
|
+
location = sessions[sessionId].location
|
|
2576
|
+
}
|
|
2577
|
+
// console.log(`updateUserLocation sessionId:${sessionId} oldWS:${oldLocation?.workspace} newWS:${location.workspace}`)
|
|
2578
|
+
if (location.workspace) {
|
|
2579
|
+
getWorkspaceTray(location.workspace).addUser(sessionId)
|
|
2580
|
+
}
|
|
2581
|
+
if (location.node) {
|
|
2582
|
+
addUserToNode(sessionId, location.node)
|
|
2583
|
+
viewTouched = true
|
|
2584
|
+
}
|
|
2585
|
+
if (viewTouched) {
|
|
2586
|
+
RED.view.redraw()
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
// function refreshUserLocations () {
|
|
2591
|
+
// for (const session of Object.keys(sessions)) {
|
|
2592
|
+
// if (session !== activeSessionId) {
|
|
2593
|
+
// updateUserLocation(session)
|
|
2594
|
+
// }
|
|
2595
|
+
// }
|
|
2596
|
+
// }
|
|
2597
|
+
|
|
2598
|
+
return {
|
|
2599
|
+
init: function () {
|
|
2600
|
+
|
|
2601
|
+
function createAnnotationUser(user) {
|
|
2602
|
+
|
|
2603
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
2604
|
+
const badge = document.createElementNS("http://www.w3.org/2000/svg","circle");
|
|
2605
|
+
const radius = 20
|
|
2606
|
+
badge.setAttribute("cx",radius/2);
|
|
2607
|
+
badge.setAttribute("cy",radius/2);
|
|
2608
|
+
badge.setAttribute("r",radius/2);
|
|
2609
|
+
badge.setAttribute("class", "red-ui-multiplayer-annotation-background")
|
|
2610
|
+
group.appendChild(badge)
|
|
2611
|
+
if (user && user.profileColor !== undefined) {
|
|
2612
|
+
badge.setAttribute("class", "red-ui-multiplayer-annotation-background red-ui-user-profile-color-" + user.profileColor)
|
|
2613
|
+
}
|
|
2614
|
+
if (user && user.image) {
|
|
2615
|
+
const image = document.createElementNS("http://www.w3.org/2000/svg","image");
|
|
2616
|
+
image.setAttribute("width", radius)
|
|
2617
|
+
image.setAttribute("height", radius)
|
|
2618
|
+
image.setAttribute("href", user.image)
|
|
2619
|
+
image.setAttribute("clip-path", "circle("+Math.floor(radius/2)+")")
|
|
2620
|
+
group.appendChild(image)
|
|
2621
|
+
} else if (user && user.anonymous) {
|
|
2622
|
+
const anonIconHead = document.createElementNS("http://www.w3.org/2000/svg","circle");
|
|
2623
|
+
anonIconHead.setAttribute("cx", radius/2)
|
|
2624
|
+
anonIconHead.setAttribute("cy", radius/2 - 2)
|
|
2625
|
+
anonIconHead.setAttribute("r", 2.4)
|
|
2626
|
+
anonIconHead.setAttribute("class","red-ui-multiplayer-annotation-anon-label");
|
|
2627
|
+
group.appendChild(anonIconHead)
|
|
2628
|
+
const anonIconBody = document.createElementNS("http://www.w3.org/2000/svg","path");
|
|
2629
|
+
anonIconBody.setAttribute("class","red-ui-multiplayer-annotation-anon-label");
|
|
2630
|
+
// anonIconBody.setAttribute("d",`M ${radius/2 - 4} ${radius/2 + 1} h 8 v4 h -8 z`);
|
|
2631
|
+
anonIconBody.setAttribute("d",`M ${radius/2} ${radius/2 + 5} h -2.5 c -2 1 -2 -5 0.5 -4.5 c 2 1 2 1 4 0 c 2.5 -0.5 2.5 5.5 0 4.5 z`);
|
|
2632
|
+
group.appendChild(anonIconBody)
|
|
2633
|
+
} else {
|
|
2634
|
+
const labelText = user.username ? user.username.substring(0,2) : user
|
|
2635
|
+
const label = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
2636
|
+
if (user.username) {
|
|
2637
|
+
label.setAttribute("class","red-ui-multiplayer-annotation-label");
|
|
2638
|
+
label.textContent = user.username.substring(0,2)
|
|
2639
|
+
} else {
|
|
2640
|
+
label.setAttribute("class","red-ui-multiplayer-annotation-label red-ui-multiplayer-user-count")
|
|
2641
|
+
label.textContent = user
|
|
2642
|
+
}
|
|
2643
|
+
label.setAttribute("text-anchor", "middle")
|
|
2644
|
+
label.setAttribute("x",radius/2);
|
|
2645
|
+
label.setAttribute("y",radius/2 + 3);
|
|
2646
|
+
group.appendChild(label)
|
|
2647
|
+
}
|
|
2648
|
+
const border = document.createElementNS("http://www.w3.org/2000/svg","circle");
|
|
2649
|
+
border.setAttribute("cx",radius/2);
|
|
2650
|
+
border.setAttribute("cy",radius/2);
|
|
2651
|
+
border.setAttribute("r",radius/2);
|
|
2652
|
+
border.setAttribute("class", "red-ui-multiplayer-annotation-border")
|
|
2653
|
+
group.appendChild(border)
|
|
2654
|
+
|
|
2655
|
+
|
|
2656
|
+
|
|
2657
|
+
return group
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
RED.view.annotations.register("red-ui-multiplayer",{
|
|
2661
|
+
type: 'badge',
|
|
2662
|
+
align: 'left',
|
|
2663
|
+
class: "red-ui-multiplayer-annotation",
|
|
2664
|
+
show: "_multiplayer",
|
|
2665
|
+
refresh: "_multiplayer_refresh",
|
|
2666
|
+
element: function(node) {
|
|
2667
|
+
const containerGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
2668
|
+
containerGroup.setAttribute("transform","translate(0,-4)")
|
|
2669
|
+
if (node._multiplayer) {
|
|
2670
|
+
let y = 0
|
|
2671
|
+
for (let i = Math.min(1, node._multiplayer.users.length - 1); i >= 0; i--) {
|
|
2672
|
+
const user = sessions[node._multiplayer.users[i]].user
|
|
2673
|
+
const group = createAnnotationUser(user)
|
|
2674
|
+
group.setAttribute("transform","translate("+y+",0)")
|
|
2675
|
+
y += 15
|
|
2676
|
+
containerGroup.appendChild(group)
|
|
2677
|
+
}
|
|
2678
|
+
if (node._multiplayer.users.length > 2) {
|
|
2679
|
+
const group = createAnnotationUser('+'+(node._multiplayer.users.length - 2))
|
|
2680
|
+
group.setAttribute("transform","translate("+y+",0)")
|
|
2681
|
+
y += 12
|
|
2682
|
+
containerGroup.appendChild(group)
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
}
|
|
2686
|
+
return containerGroup;
|
|
2687
|
+
},
|
|
2688
|
+
tooltip: node => { return node._multiplayer.users.map(u => sessions[u].user.username).join('\n') }
|
|
2689
|
+
});
|
|
2690
|
+
|
|
2691
|
+
|
|
2692
|
+
// activeSessionId = RED.settings.getLocal('multiplayer:sessionId')
|
|
2693
|
+
// if (!activeSessionId) {
|
|
2694
|
+
activeSessionId = RED.nodes.id()
|
|
2695
|
+
// RED.settings.setLocal('multiplayer:sessionId', activeSessionId)
|
|
2696
|
+
// log('Session ID (new)', activeSessionId)
|
|
2697
|
+
// } else {
|
|
2698
|
+
log('Session ID', activeSessionId)
|
|
2699
|
+
// }
|
|
2700
|
+
|
|
2701
|
+
headerWidget = $('<li><ul id="red-ui-multiplayer-user-list"></ul></li>').prependTo('.red-ui-header-toolbar')
|
|
2702
|
+
|
|
2703
|
+
RED.comms.on('connect', () => {
|
|
2704
|
+
const location = getLocation()
|
|
2705
|
+
const connectInfo = {
|
|
2706
|
+
session: activeSessionId
|
|
2707
|
+
}
|
|
2708
|
+
if (location.workspace !== 0) {
|
|
2709
|
+
connectInfo.location = location
|
|
2710
|
+
}
|
|
2711
|
+
RED.comms.send('multiplayer/connect', connectInfo)
|
|
2712
|
+
})
|
|
2713
|
+
RED.comms.subscribe('multiplayer/#', (topic, msg) => {
|
|
2714
|
+
log('recv', topic, msg)
|
|
2715
|
+
if (topic === 'multiplayer/init') {
|
|
2716
|
+
// We have just reconnected, runtime has sent state to
|
|
2717
|
+
// initialise the world
|
|
2718
|
+
sessions = {}
|
|
2719
|
+
users = {}
|
|
2720
|
+
$('#red-ui-multiplayer-user-list').empty()
|
|
2721
|
+
|
|
2722
|
+
msg.sessions.forEach(session => {
|
|
2723
|
+
addUserSession(session)
|
|
2724
|
+
})
|
|
2725
|
+
} else if (topic === 'multiplayer/connection-added') {
|
|
2726
|
+
addUserSession(msg)
|
|
2727
|
+
} else if (topic === 'multiplayer/connection-removed') {
|
|
2728
|
+
removeUserSession(msg.session, msg.disconnected)
|
|
2729
|
+
} else if (topic === 'multiplayer/location') {
|
|
2730
|
+
const session = msg.session
|
|
2731
|
+
delete msg.session
|
|
2732
|
+
updateUserLocation(session, msg)
|
|
2733
|
+
}
|
|
2734
|
+
})
|
|
2735
|
+
|
|
2736
|
+
RED.events.on('workspace:change', (event) => {
|
|
2737
|
+
getWorkspaceTray(event.workspace)
|
|
2738
|
+
publishLocation()
|
|
2739
|
+
})
|
|
2740
|
+
RED.events.on('editor:open', () => {
|
|
2741
|
+
publishLocation()
|
|
2742
|
+
})
|
|
2743
|
+
RED.events.on('editor:close', () => {
|
|
2744
|
+
publishLocation()
|
|
2745
|
+
})
|
|
2746
|
+
RED.events.on('editor:change', () => {
|
|
2747
|
+
publishLocation()
|
|
2748
|
+
})
|
|
2749
|
+
RED.events.on('login', () => {
|
|
2750
|
+
publishLocation()
|
|
2751
|
+
})
|
|
2752
|
+
RED.events.on('flows:loaded', () => {
|
|
2753
|
+
attachWorkspaceTrays()
|
|
2754
|
+
})
|
|
2755
|
+
RED.events.on('workspace:close', (event) => {
|
|
2756
|
+
// A subflow tab has been closed. Need to mark its tray as detached
|
|
2757
|
+
if (workspaceTrays[event.workspace]) {
|
|
2758
|
+
workspaceTrays[event.workspace].attached = false
|
|
2759
|
+
}
|
|
2760
|
+
})
|
|
2761
|
+
RED.events.on('logout', () => {
|
|
2762
|
+
const disconnectInfo = {
|
|
2763
|
+
session: activeSessionId
|
|
2764
|
+
}
|
|
2765
|
+
RED.comms.send('multiplayer/disconnect', disconnectInfo)
|
|
2766
|
+
RED.settings.removeLocal('multiplayer:sessionId')
|
|
2767
|
+
})
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
function log() {
|
|
2772
|
+
if (RED.multiplayer.DEBUG) {
|
|
2773
|
+
console.log('[multiplayer]', ...arguments)
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
})();
|
|
2178
2777
|
;/**
|
|
2179
2778
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
|
2180
2779
|
*
|
|
@@ -3672,6 +4271,7 @@ RED.state = {
|
|
|
3672
4271
|
;RED.plugins = (function() {
|
|
3673
4272
|
var plugins = {};
|
|
3674
4273
|
var pluginsByType = {};
|
|
4274
|
+
var moduleList = {};
|
|
3675
4275
|
|
|
3676
4276
|
function registerPlugin(id,definition) {
|
|
3677
4277
|
plugins[id] = definition;
|
|
@@ -3709,10 +4309,44 @@ RED.state = {
|
|
|
3709
4309
|
function getPluginsByType(type) {
|
|
3710
4310
|
return pluginsByType[type] || [];
|
|
3711
4311
|
}
|
|
4312
|
+
|
|
4313
|
+
function setPluginList(list) {
|
|
4314
|
+
for(let i=0;i<list.length;i++) {
|
|
4315
|
+
let p = list[i];
|
|
4316
|
+
addPlugin(p);
|
|
4317
|
+
}
|
|
4318
|
+
}
|
|
4319
|
+
|
|
4320
|
+
function addPlugin(p) {
|
|
4321
|
+
|
|
4322
|
+
moduleList[p.module] = moduleList[p.module] || {
|
|
4323
|
+
name:p.module,
|
|
4324
|
+
version:p.version,
|
|
4325
|
+
local:p.local,
|
|
4326
|
+
sets:{},
|
|
4327
|
+
plugin: true,
|
|
4328
|
+
id: p.id
|
|
4329
|
+
};
|
|
4330
|
+
if (p.pending_version) {
|
|
4331
|
+
moduleList[p.module].pending_version = p.pending_version;
|
|
4332
|
+
}
|
|
4333
|
+
moduleList[p.module].sets[p.name] = p;
|
|
4334
|
+
|
|
4335
|
+
RED.events.emit("registry:plugin-module-added",p.module);
|
|
4336
|
+
}
|
|
4337
|
+
|
|
4338
|
+
function getModule(module) {
|
|
4339
|
+
return moduleList[module];
|
|
4340
|
+
}
|
|
4341
|
+
|
|
3712
4342
|
return {
|
|
3713
4343
|
registerPlugin: registerPlugin,
|
|
3714
4344
|
getPlugin: getPlugin,
|
|
3715
|
-
getPluginsByType: getPluginsByType
|
|
4345
|
+
getPluginsByType: getPluginsByType,
|
|
4346
|
+
|
|
4347
|
+
setPluginList: setPluginList,
|
|
4348
|
+
addPlugin: addPlugin,
|
|
4349
|
+
getModule: getModule
|
|
3716
4350
|
}
|
|
3717
4351
|
})();
|
|
3718
4352
|
;/**
|
|
@@ -3866,6 +4500,8 @@ RED.nodes = (function() {
|
|
|
3866
4500
|
},
|
|
3867
4501
|
removeNodeSet: function(id) {
|
|
3868
4502
|
var ns = nodeSets[id];
|
|
4503
|
+
if (!ns) { return {} }
|
|
4504
|
+
|
|
3869
4505
|
for (var j=0;j<ns.types.length;j++) {
|
|
3870
4506
|
delete typeToId[ns.types[j]];
|
|
3871
4507
|
}
|
|
@@ -4289,12 +4925,16 @@ RED.nodes = (function() {
|
|
|
4289
4925
|
* @param {String} z tab id
|
|
4290
4926
|
*/
|
|
4291
4927
|
checkTabState: function (z) {
|
|
4292
|
-
const ws = workspaces[z]
|
|
4928
|
+
const ws = workspaces[z] || subflows[z]
|
|
4293
4929
|
if (ws) {
|
|
4294
4930
|
const contentsChanged = tabDirtyMap[z].size > 0 || tabDeletedNodesMap[z].size > 0
|
|
4295
4931
|
if (Boolean(ws.contentsChanged) !== contentsChanged) {
|
|
4296
4932
|
ws.contentsChanged = contentsChanged
|
|
4297
|
-
|
|
4933
|
+
if (ws.type === 'tab') {
|
|
4934
|
+
RED.events.emit("flows:change", ws);
|
|
4935
|
+
} else {
|
|
4936
|
+
RED.events.emit("subflows:change", ws);
|
|
4937
|
+
}
|
|
4298
4938
|
}
|
|
4299
4939
|
}
|
|
4300
4940
|
}
|
|
@@ -4767,7 +5407,22 @@ RED.nodes = (function() {
|
|
|
4767
5407
|
RED.nodes.registerType("subflow:"+sf.id, {
|
|
4768
5408
|
defaults:{
|
|
4769
5409
|
name:{value:""},
|
|
4770
|
-
env:{value:[]
|
|
5410
|
+
env:{value:[], validate: function(value) {
|
|
5411
|
+
const errors = []
|
|
5412
|
+
if (value) {
|
|
5413
|
+
value.forEach(env => {
|
|
5414
|
+
const r = RED.utils.validateTypedProperty(env.value, env.type)
|
|
5415
|
+
if (r !== true) {
|
|
5416
|
+
errors.push(env.name+': '+r)
|
|
5417
|
+
}
|
|
5418
|
+
})
|
|
5419
|
+
}
|
|
5420
|
+
if (errors.length === 0) {
|
|
5421
|
+
return true
|
|
5422
|
+
} else {
|
|
5423
|
+
return errors
|
|
5424
|
+
}
|
|
5425
|
+
}}
|
|
4771
5426
|
},
|
|
4772
5427
|
icon: function() { return sf.icon||"subflow.svg" },
|
|
4773
5428
|
category: sf.category || "subflows",
|
|
@@ -7716,7 +8371,14 @@ RED.history = (function() {
|
|
|
7716
8371
|
}
|
|
7717
8372
|
return RED.nodes.junction(id);
|
|
7718
8373
|
}
|
|
7719
|
-
|
|
8374
|
+
function ensureUnlocked(id, flowsToLock) {
|
|
8375
|
+
const flow = id && (RED.nodes.workspace(id) || RED.nodes.subflow(id) || null);
|
|
8376
|
+
const isLocked = flow ? flow.locked : false;
|
|
8377
|
+
if (flow && isLocked) {
|
|
8378
|
+
flow.locked = false;
|
|
8379
|
+
flowsToLock.add(flow)
|
|
8380
|
+
}
|
|
8381
|
+
}
|
|
7720
8382
|
function undoEvent(ev) {
|
|
7721
8383
|
var i;
|
|
7722
8384
|
var len;
|
|
@@ -7746,18 +8408,46 @@ RED.history = (function() {
|
|
|
7746
8408
|
t: 'replace',
|
|
7747
8409
|
config: RED.nodes.createCompleteNodeSet(),
|
|
7748
8410
|
changed: {},
|
|
7749
|
-
|
|
8411
|
+
moved: {},
|
|
8412
|
+
complete: true,
|
|
8413
|
+
rev: RED.nodes.version(),
|
|
8414
|
+
dirty: RED.nodes.dirty()
|
|
7750
8415
|
};
|
|
8416
|
+
var selectedTab = RED.workspaces.active();
|
|
8417
|
+
inverseEv.config.forEach(n => {
|
|
8418
|
+
const node = RED.nodes.node(n.id)
|
|
8419
|
+
if (node) {
|
|
8420
|
+
inverseEv.changed[n.id] = node.changed
|
|
8421
|
+
inverseEv.moved[n.id] = node.moved
|
|
8422
|
+
}
|
|
8423
|
+
})
|
|
7751
8424
|
RED.nodes.clear();
|
|
7752
8425
|
var imported = RED.nodes.import(ev.config);
|
|
8426
|
+
// Clear all change flags from the import
|
|
8427
|
+
RED.nodes.dirty(false);
|
|
8428
|
+
|
|
8429
|
+
const flowsToLock = new Set()
|
|
8430
|
+
|
|
7753
8431
|
imported.nodes.forEach(function(n) {
|
|
7754
8432
|
if (ev.changed[n.id]) {
|
|
8433
|
+
ensureUnlocked(n.z, flowsToLock)
|
|
7755
8434
|
n.changed = true;
|
|
7756
|
-
|
|
8435
|
+
}
|
|
8436
|
+
if (ev.moved[n.id]) {
|
|
8437
|
+
ensureUnlocked(n.z, flowsToLock)
|
|
8438
|
+
n.moved = true;
|
|
7757
8439
|
}
|
|
7758
8440
|
})
|
|
8441
|
+
flowsToLock.forEach(flow => {
|
|
8442
|
+
flow.locked = true
|
|
8443
|
+
})
|
|
7759
8444
|
|
|
7760
8445
|
RED.nodes.version(ev.rev);
|
|
8446
|
+
RED.view.redraw(true);
|
|
8447
|
+
RED.palette.refresh();
|
|
8448
|
+
RED.workspaces.refresh();
|
|
8449
|
+
RED.workspaces.show(selectedTab, true);
|
|
8450
|
+
RED.sidebar.config.refresh();
|
|
7761
8451
|
} else {
|
|
7762
8452
|
var importMap = {};
|
|
7763
8453
|
ev.config.forEach(function(n) {
|
|
@@ -12309,7 +12999,7 @@ RED.popover = (function() {
|
|
|
12309
12999
|
closePopup(true);
|
|
12310
13000
|
});
|
|
12311
13001
|
}
|
|
12312
|
-
if (trigger === 'hover' && options.interactive) {
|
|
13002
|
+
if (/*trigger === 'hover' && */options.interactive) {
|
|
12313
13003
|
div.on('mouseenter', function(e) {
|
|
12314
13004
|
clearTimeout(timer);
|
|
12315
13005
|
active = true;
|
|
@@ -12543,9 +13233,12 @@ RED.popover = (function() {
|
|
|
12543
13233
|
|
|
12544
13234
|
return {
|
|
12545
13235
|
create: createPopover,
|
|
12546
|
-
tooltip: function(target,content, action) {
|
|
13236
|
+
tooltip: function(target,content, action, interactive) {
|
|
12547
13237
|
var label = function() {
|
|
12548
13238
|
var label = content;
|
|
13239
|
+
if (typeof content === 'function') {
|
|
13240
|
+
label = content()
|
|
13241
|
+
}
|
|
12549
13242
|
if (action) {
|
|
12550
13243
|
var shortcut = RED.keyboard.getShortcut(action);
|
|
12551
13244
|
if (shortcut && shortcut.key) {
|
|
@@ -12561,6 +13254,7 @@ RED.popover = (function() {
|
|
|
12561
13254
|
size: "small",
|
|
12562
13255
|
direction: "bottom",
|
|
12563
13256
|
content: label,
|
|
13257
|
+
interactive,
|
|
12564
13258
|
delay: { show: 750, hide: 50 }
|
|
12565
13259
|
});
|
|
12566
13260
|
popover.setContent = function(newContent) {
|
|
@@ -13319,7 +14013,10 @@ RED.tabs = (function() {
|
|
|
13319
14013
|
|
|
13320
14014
|
var thisTabA = thisTab.find("a");
|
|
13321
14015
|
if (options.onclick) {
|
|
13322
|
-
options.onclick(tabs[thisTabA.attr('href').slice(1)]);
|
|
14016
|
+
options.onclick(tabs[thisTabA.attr('href').slice(1)], evt);
|
|
14017
|
+
if (evt.isDefaultPrevented() && evt.isPropagationStopped()) {
|
|
14018
|
+
return false
|
|
14019
|
+
}
|
|
13323
14020
|
}
|
|
13324
14021
|
activateTab(thisTabA);
|
|
13325
14022
|
if (fireSelectionChanged) {
|
|
@@ -13502,6 +14199,8 @@ RED.tabs = (function() {
|
|
|
13502
14199
|
ul.find("li.red-ui-tab a")
|
|
13503
14200
|
.on("mousedown", function(evt) { mousedownTab = evt.currentTarget })
|
|
13504
14201
|
.on("mouseup",onTabClick)
|
|
14202
|
+
// prevent browser-default middle-click behaviour
|
|
14203
|
+
.on("auxclick", function(evt) { evt.preventDefault() })
|
|
13505
14204
|
.on("click", function(evt) {evt.preventDefault(); })
|
|
13506
14205
|
.on("dblclick", function(evt) {evt.stopPropagation(); evt.preventDefault(); })
|
|
13507
14206
|
|
|
@@ -13770,6 +14469,8 @@ RED.tabs = (function() {
|
|
|
13770
14469
|
}
|
|
13771
14470
|
link.on("mousedown", function(evt) { mousedownTab = evt.currentTarget })
|
|
13772
14471
|
link.on("mouseup",onTabClick);
|
|
14472
|
+
// prevent browser-default middle-click behaviour
|
|
14473
|
+
link.on("auxclick", function(evt) { evt.preventDefault() })
|
|
13773
14474
|
link.on("click", function(evt) { evt.preventDefault(); })
|
|
13774
14475
|
link.on("dblclick", function(evt) { evt.stopPropagation(); evt.preventDefault(); })
|
|
13775
14476
|
|
|
@@ -16137,6 +16838,8 @@ RED.deploy = (function() {
|
|
|
16137
16838
|
|
|
16138
16839
|
var currentDiff = null;
|
|
16139
16840
|
|
|
16841
|
+
var activeBackgroundDeployNotification;
|
|
16842
|
+
|
|
16140
16843
|
function changeDeploymentType(type) {
|
|
16141
16844
|
deploymentType = type;
|
|
16142
16845
|
$("#red-ui-header-button-deploy-icon").attr("src",deploymentTypes[type].img);
|
|
@@ -16215,51 +16918,59 @@ RED.deploy = (function() {
|
|
|
16215
16918
|
RED.actions.add("core:set-deploy-type-to-modified-nodes",function() { RED.menu.setSelected("deploymenu-item-node",true); });
|
|
16216
16919
|
}
|
|
16217
16920
|
|
|
16218
|
-
|
|
16921
|
+
window.addEventListener('beforeunload', function (event) {
|
|
16922
|
+
if (RED.nodes.dirty()) {
|
|
16923
|
+
event.preventDefault();
|
|
16924
|
+
event.stopImmediatePropagation()
|
|
16925
|
+
event.returnValue = RED._("deploy.confirm.undeployedChanges");
|
|
16926
|
+
return
|
|
16927
|
+
}
|
|
16928
|
+
})
|
|
16219
16929
|
|
|
16220
16930
|
RED.events.on('workspace:dirty',function(state) {
|
|
16221
16931
|
if (state.dirty) {
|
|
16222
|
-
window.onbeforeunload = function() {
|
|
16223
|
-
|
|
16224
|
-
}
|
|
16932
|
+
// window.onbeforeunload = function() {
|
|
16933
|
+
// return
|
|
16934
|
+
// }
|
|
16225
16935
|
$("#red-ui-header-button-deploy").removeClass("disabled");
|
|
16226
16936
|
} else {
|
|
16227
|
-
window.onbeforeunload = null;
|
|
16937
|
+
// window.onbeforeunload = null;
|
|
16228
16938
|
$("#red-ui-header-button-deploy").addClass("disabled");
|
|
16229
16939
|
}
|
|
16230
16940
|
});
|
|
16231
16941
|
|
|
16232
|
-
var activeNotifyMessage;
|
|
16233
16942
|
RED.comms.subscribe("notification/runtime-deploy",function(topic,msg) {
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16249
|
-
|
|
16250
|
-
|
|
16251
|
-
|
|
16252
|
-
|
|
16253
|
-
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
resolveConflict(nns,false);
|
|
16258
|
-
activeNotifyMessage = null;
|
|
16259
|
-
}
|
|
16943
|
+
var currentRev = RED.nodes.version();
|
|
16944
|
+
if (currentRev === null || deployInflight || currentRev === msg.revision) {
|
|
16945
|
+
return;
|
|
16946
|
+
}
|
|
16947
|
+
if (activeBackgroundDeployNotification?.hidden && !activeBackgroundDeployNotification?.closed) {
|
|
16948
|
+
activeBackgroundDeployNotification.showNotification()
|
|
16949
|
+
return
|
|
16950
|
+
}
|
|
16951
|
+
const message = $('<p>').text(RED._('deploy.confirm.backgroundUpdate'));
|
|
16952
|
+
const options = {
|
|
16953
|
+
id: 'background-update',
|
|
16954
|
+
type: 'compact',
|
|
16955
|
+
modal: false,
|
|
16956
|
+
fixed: true,
|
|
16957
|
+
timeout: 10000,
|
|
16958
|
+
buttons: [
|
|
16959
|
+
{
|
|
16960
|
+
text: RED._('deploy.confirm.button.review'),
|
|
16961
|
+
class: "primary",
|
|
16962
|
+
click: function() {
|
|
16963
|
+
activeBackgroundDeployNotification.hideNotification();
|
|
16964
|
+
var nns = RED.nodes.createCompleteNodeSet();
|
|
16965
|
+
resolveConflict(nns,false);
|
|
16260
16966
|
}
|
|
16261
|
-
|
|
16262
|
-
|
|
16967
|
+
}
|
|
16968
|
+
]
|
|
16969
|
+
}
|
|
16970
|
+
if (!activeBackgroundDeployNotification || activeBackgroundDeployNotification.closed) {
|
|
16971
|
+
activeBackgroundDeployNotification = RED.notify(message, options)
|
|
16972
|
+
} else {
|
|
16973
|
+
activeBackgroundDeployNotification.update(message, options)
|
|
16263
16974
|
}
|
|
16264
16975
|
});
|
|
16265
16976
|
}
|
|
@@ -16316,7 +17027,11 @@ RED.deploy = (function() {
|
|
|
16316
17027
|
class: "primary disabled",
|
|
16317
17028
|
click: function() {
|
|
16318
17029
|
if (!$("#red-ui-deploy-dialog-confirm-deploy-review").hasClass('disabled')) {
|
|
16319
|
-
RED.diff.showRemoteDiff(
|
|
17030
|
+
RED.diff.showRemoteDiff(null, {
|
|
17031
|
+
onmerge: function () {
|
|
17032
|
+
activeBackgroundDeployNotification.close()
|
|
17033
|
+
}
|
|
17034
|
+
});
|
|
16320
17035
|
conflictNotification.close();
|
|
16321
17036
|
}
|
|
16322
17037
|
}
|
|
@@ -16329,6 +17044,7 @@ RED.deploy = (function() {
|
|
|
16329
17044
|
if (!$("#red-ui-deploy-dialog-confirm-deploy-merge").hasClass('disabled')) {
|
|
16330
17045
|
RED.diff.mergeDiff(currentDiff);
|
|
16331
17046
|
conflictNotification.close();
|
|
17047
|
+
activeBackgroundDeployNotification.close()
|
|
16332
17048
|
}
|
|
16333
17049
|
}
|
|
16334
17050
|
}
|
|
@@ -16341,6 +17057,7 @@ RED.deploy = (function() {
|
|
|
16341
17057
|
click: function() {
|
|
16342
17058
|
save(true,activeDeploy);
|
|
16343
17059
|
conflictNotification.close();
|
|
17060
|
+
activeBackgroundDeployNotification.close()
|
|
16344
17061
|
}
|
|
16345
17062
|
})
|
|
16346
17063
|
}
|
|
@@ -16351,21 +17068,17 @@ RED.deploy = (function() {
|
|
|
16351
17068
|
buttons: buttons
|
|
16352
17069
|
});
|
|
16353
17070
|
|
|
16354
|
-
var now = Date.now();
|
|
16355
17071
|
RED.diff.getRemoteDiff(function(diff) {
|
|
16356
|
-
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
|
16357
17072
|
currentDiff = diff;
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
|
|
16362
|
-
|
|
16363
|
-
|
|
16364
|
-
|
|
16365
|
-
|
|
16366
|
-
|
|
16367
|
-
$("#red-ui-deploy-dialog-confirm-deploy-review").removeClass('disabled')
|
|
16368
|
-
},ellapsed);
|
|
17073
|
+
conflictCheck.hide();
|
|
17074
|
+
var d = Object.keys(diff.conflicts);
|
|
17075
|
+
if (d.length === 0) {
|
|
17076
|
+
conflictAutoMerge.show();
|
|
17077
|
+
$("#red-ui-deploy-dialog-confirm-deploy-merge").removeClass('disabled')
|
|
17078
|
+
} else {
|
|
17079
|
+
conflictManualMerge.show();
|
|
17080
|
+
}
|
|
17081
|
+
$("#red-ui-deploy-dialog-confirm-deploy-review").removeClass('disabled')
|
|
16369
17082
|
})
|
|
16370
17083
|
}
|
|
16371
17084
|
function cropList(list) {
|
|
@@ -16715,7 +17428,10 @@ RED.deploy = (function() {
|
|
|
16715
17428
|
}
|
|
16716
17429
|
});
|
|
16717
17430
|
RED.nodes.eachSubflow(function (subflow) {
|
|
16718
|
-
subflow.changed
|
|
17431
|
+
if (subflow.changed) {
|
|
17432
|
+
subflow.changed = false;
|
|
17433
|
+
RED.events.emit("subflows:change", subflow);
|
|
17434
|
+
}
|
|
16719
17435
|
});
|
|
16720
17436
|
RED.nodes.eachWorkspace(function (ws) {
|
|
16721
17437
|
if (ws.changed || ws.added) {
|
|
@@ -16823,7 +17539,6 @@ RED.diagnostics = (function () {
|
|
|
16823
17539
|
};
|
|
16824
17540
|
})();
|
|
16825
17541
|
;RED.diff = (function() {
|
|
16826
|
-
|
|
16827
17542
|
var currentDiff = {};
|
|
16828
17543
|
var diffVisible = false;
|
|
16829
17544
|
var diffList;
|
|
@@ -16886,12 +17601,14 @@ RED.diagnostics = (function () {
|
|
|
16886
17601
|
addedCount:0,
|
|
16887
17602
|
deletedCount:0,
|
|
16888
17603
|
changedCount:0,
|
|
17604
|
+
movedCount:0,
|
|
16889
17605
|
unchangedCount: 0
|
|
16890
17606
|
},
|
|
16891
17607
|
remote: {
|
|
16892
17608
|
addedCount:0,
|
|
16893
17609
|
deletedCount:0,
|
|
16894
17610
|
changedCount:0,
|
|
17611
|
+
movedCount:0,
|
|
16895
17612
|
unchangedCount: 0
|
|
16896
17613
|
},
|
|
16897
17614
|
conflicts: 0
|
|
@@ -16962,7 +17679,7 @@ RED.diagnostics = (function () {
|
|
|
16962
17679
|
$(this).parent().toggleClass('collapsed');
|
|
16963
17680
|
});
|
|
16964
17681
|
|
|
16965
|
-
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode
|
|
17682
|
+
createNodePropertiesTable(def,tab,localTabNode,remoteTabNode).appendTo(div);
|
|
16966
17683
|
selectState = "";
|
|
16967
17684
|
if (conflicts[tab.id]) {
|
|
16968
17685
|
flowStats.conflicts++;
|
|
@@ -17032,19 +17749,26 @@ RED.diagnostics = (function () {
|
|
|
17032
17749
|
var localStats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(localCell);
|
|
17033
17750
|
$('<span class="red-ui-diff-status"></span>').text(RED._('diff.nodeCount',{count:localNodeCount})).appendTo(localStats);
|
|
17034
17751
|
|
|
17035
|
-
if (flowStats.conflicts + flowStats.local.addedCount + flowStats.local.changedCount + flowStats.local.deletedCount > 0) {
|
|
17752
|
+
if (flowStats.conflicts + flowStats.local.addedCount + flowStats.local.changedCount + flowStats.local.movedCount + flowStats.local.deletedCount > 0) {
|
|
17036
17753
|
$('<span class="red-ui-diff-status"> [ </span>').appendTo(localStats);
|
|
17037
17754
|
if (flowStats.conflicts > 0) {
|
|
17038
17755
|
$('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i> '+flowStats.conflicts+'</span></span>').appendTo(localStats);
|
|
17039
17756
|
}
|
|
17040
17757
|
if (flowStats.local.addedCount > 0) {
|
|
17041
|
-
$('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.local.addedCount+'</span></span>').appendTo(localStats);
|
|
17758
|
+
const cell = $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.local.addedCount+'</span></span>').appendTo(localStats);
|
|
17759
|
+
RED.popover.tooltip(cell, RED._('diff.type.added'))
|
|
17042
17760
|
}
|
|
17043
17761
|
if (flowStats.local.changedCount > 0) {
|
|
17044
|
-
$('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.changedCount+'</span></span>').appendTo(localStats);
|
|
17762
|
+
const cell = $('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.changedCount+'</span></span>').appendTo(localStats);
|
|
17763
|
+
RED.popover.tooltip(cell, RED._('diff.type.changed'))
|
|
17764
|
+
}
|
|
17765
|
+
if (flowStats.local.movedCount > 0) {
|
|
17766
|
+
const cell = $('<span class="red-ui-diff-status-moved"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.movedCount+'</span></span>').appendTo(localStats);
|
|
17767
|
+
RED.popover.tooltip(cell, RED._('diff.type.moved'))
|
|
17045
17768
|
}
|
|
17046
17769
|
if (flowStats.local.deletedCount > 0) {
|
|
17047
|
-
$('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.local.deletedCount+'</span></span>').appendTo(localStats);
|
|
17770
|
+
const cell = $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.local.deletedCount+'</span></span>').appendTo(localStats);
|
|
17771
|
+
RED.popover.tooltip(cell, RED._('diff.type.deleted'))
|
|
17048
17772
|
}
|
|
17049
17773
|
$('<span class="red-ui-diff-status"> ] </span>').appendTo(localStats);
|
|
17050
17774
|
}
|
|
@@ -17070,19 +17794,26 @@ RED.diagnostics = (function () {
|
|
|
17070
17794
|
}
|
|
17071
17795
|
var remoteStats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(remoteCell);
|
|
17072
17796
|
$('<span class="red-ui-diff-status"></span>').text(RED._('diff.nodeCount',{count:remoteNodeCount})).appendTo(remoteStats);
|
|
17073
|
-
if (flowStats.conflicts + flowStats.remote.addedCount + flowStats.remote.changedCount + flowStats.remote.deletedCount > 0) {
|
|
17797
|
+
if (flowStats.conflicts + flowStats.remote.addedCount + flowStats.remote.changedCount + flowStats.remote.movedCount + flowStats.remote.deletedCount > 0) {
|
|
17074
17798
|
$('<span class="red-ui-diff-status"> [ </span>').appendTo(remoteStats);
|
|
17075
17799
|
if (flowStats.conflicts > 0) {
|
|
17076
17800
|
$('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i> '+flowStats.conflicts+'</span></span>').appendTo(remoteStats);
|
|
17077
17801
|
}
|
|
17078
17802
|
if (flowStats.remote.addedCount > 0) {
|
|
17079
|
-
$('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.remote.addedCount+'</span></span>').appendTo(remoteStats);
|
|
17803
|
+
const cell = $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.remote.addedCount+'</span></span>').appendTo(remoteStats);
|
|
17804
|
+
RED.popover.tooltip(cell, RED._('diff.type.added'))
|
|
17080
17805
|
}
|
|
17081
17806
|
if (flowStats.remote.changedCount > 0) {
|
|
17082
|
-
$('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.changedCount+'</span></span>').appendTo(remoteStats);
|
|
17807
|
+
const cell = $('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.changedCount+'</span></span>').appendTo(remoteStats);
|
|
17808
|
+
RED.popover.tooltip(cell, RED._('diff.type.changed'))
|
|
17809
|
+
}
|
|
17810
|
+
if (flowStats.remote.movedCount > 0) {
|
|
17811
|
+
const cell = $('<span class="red-ui-diff-status-moved"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.movedCount+'</span></span>').appendTo(remoteStats);
|
|
17812
|
+
RED.popover.tooltip(cell, RED._('diff.type.moved'))
|
|
17083
17813
|
}
|
|
17084
17814
|
if (flowStats.remote.deletedCount > 0) {
|
|
17085
|
-
$('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.remote.deletedCount+'</span></span>').appendTo(remoteStats);
|
|
17815
|
+
const cell = $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.remote.deletedCount+'</span></span>').appendTo(remoteStats);
|
|
17816
|
+
RED.popover.tooltip(cell, RED._('diff.type.deleted'))
|
|
17086
17817
|
}
|
|
17087
17818
|
$('<span class="red-ui-diff-status"> ] </span>').appendTo(remoteStats);
|
|
17088
17819
|
}
|
|
@@ -17117,7 +17848,7 @@ RED.diagnostics = (function () {
|
|
|
17117
17848
|
if (options.mode === "merge") {
|
|
17118
17849
|
diffPanel.addClass("red-ui-diff-panel-merge");
|
|
17119
17850
|
}
|
|
17120
|
-
var diffList = createDiffTable(diffPanel, diff);
|
|
17851
|
+
var diffList = createDiffTable(diffPanel, diff, options);
|
|
17121
17852
|
|
|
17122
17853
|
var localDiff = diff.localDiff;
|
|
17123
17854
|
var remoteDiff = diff.remoteDiff;
|
|
@@ -17340,7 +18071,6 @@ RED.diagnostics = (function () {
|
|
|
17340
18071
|
|
|
17341
18072
|
var hasChanges = false; // exists in original and local/remote but with changes
|
|
17342
18073
|
var unChanged = true; // existing in original,local,remote unchanged
|
|
17343
|
-
var localChanged = false;
|
|
17344
18074
|
|
|
17345
18075
|
if (localDiff.added[node.id]) {
|
|
17346
18076
|
stats.local.addedCount++;
|
|
@@ -17359,12 +18089,20 @@ RED.diagnostics = (function () {
|
|
|
17359
18089
|
unChanged = false;
|
|
17360
18090
|
}
|
|
17361
18091
|
if (localDiff.changed[node.id]) {
|
|
17362
|
-
|
|
18092
|
+
if (localDiff.positionChanged[node.id]) {
|
|
18093
|
+
stats.local.movedCount++
|
|
18094
|
+
} else {
|
|
18095
|
+
stats.local.changedCount++;
|
|
18096
|
+
}
|
|
17363
18097
|
hasChanges = true;
|
|
17364
18098
|
unChanged = false;
|
|
17365
18099
|
}
|
|
17366
18100
|
if (remoteDiff && remoteDiff.changed[node.id]) {
|
|
17367
|
-
|
|
18101
|
+
if (remoteDiff.positionChanged[node.id]) {
|
|
18102
|
+
stats.remote.movedCount++
|
|
18103
|
+
} else {
|
|
18104
|
+
stats.remote.changedCount++;
|
|
18105
|
+
}
|
|
17368
18106
|
hasChanges = true;
|
|
17369
18107
|
unChanged = false;
|
|
17370
18108
|
}
|
|
@@ -17429,27 +18167,32 @@ RED.diagnostics = (function () {
|
|
|
17429
18167
|
localNodeDiv.addClass("red-ui-diff-status-moved");
|
|
17430
18168
|
var localMovedMessage = "";
|
|
17431
18169
|
if (node.z === localN.z) {
|
|
17432
|
-
|
|
18170
|
+
const movedFromNodeTab = localDiff.currentConfig.all[localDiff.currentConfig.all[node.id].z]
|
|
18171
|
+
const movedFromLabel = `'${movedFromNodeTab ? (movedFromNodeTab.label || movedFromNodeTab.id) : 'global'}'`
|
|
18172
|
+
localMovedMessage = RED._("diff.type.movedFrom",{id: movedFromLabel});
|
|
17433
18173
|
} else {
|
|
17434
|
-
|
|
18174
|
+
const movedToNodeTab = localDiff.newConfig.all[localN.z]
|
|
18175
|
+
const movedToLabel = `'${movedToNodeTab ? (movedToNodeTab.label || movedToNodeTab.id) : 'global'}'`
|
|
18176
|
+
localMovedMessage = RED._("diff.type.movedTo",{id:movedToLabel});
|
|
17435
18177
|
}
|
|
17436
18178
|
$('<span class="red-ui-diff-status"><i class="fa fa-caret-square-o-right"></i> '+localMovedMessage+'</span>').appendTo(localNodeDiv);
|
|
17437
18179
|
}
|
|
17438
|
-
localChanged = true;
|
|
17439
18180
|
} else if (localDiff.deleted[node.z]) {
|
|
17440
18181
|
localNodeDiv.addClass("red-ui-diff-empty");
|
|
17441
|
-
localChanged = true;
|
|
17442
18182
|
} else if (localDiff.deleted[node.id]) {
|
|
17443
18183
|
localNodeDiv.addClass("red-ui-diff-status-deleted");
|
|
17444
18184
|
$('<span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> <span data-i18n="diff.type.deleted"></span></span>').appendTo(localNodeDiv);
|
|
17445
|
-
localChanged = true;
|
|
17446
18185
|
} else if (localDiff.changed[node.id]) {
|
|
17447
18186
|
if (localDiff.newConfig.all[node.id].z !== node.z) {
|
|
17448
18187
|
localNodeDiv.addClass("red-ui-diff-empty");
|
|
17449
18188
|
} else {
|
|
17450
|
-
|
|
17451
|
-
|
|
17452
|
-
|
|
18189
|
+
if (localDiff.positionChanged[node.id]) {
|
|
18190
|
+
localNodeDiv.addClass("red-ui-diff-status-moved");
|
|
18191
|
+
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.moved"></span></span>').appendTo(localNodeDiv);
|
|
18192
|
+
} else {
|
|
18193
|
+
localNodeDiv.addClass("red-ui-diff-status-changed");
|
|
18194
|
+
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(localNodeDiv);
|
|
18195
|
+
}
|
|
17453
18196
|
}
|
|
17454
18197
|
} else {
|
|
17455
18198
|
if (localDiff.newConfig.all[node.id].z !== node.z) {
|
|
@@ -17470,9 +18213,13 @@ RED.diagnostics = (function () {
|
|
|
17470
18213
|
remoteNodeDiv.addClass("red-ui-diff-status-moved");
|
|
17471
18214
|
var remoteMovedMessage = "";
|
|
17472
18215
|
if (node.z === remoteN.z) {
|
|
17473
|
-
|
|
18216
|
+
const movedFromNodeTab = remoteDiff.currentConfig.all[remoteDiff.currentConfig.all[node.id].z]
|
|
18217
|
+
const movedFromLabel = `'${movedFromNodeTab ? (movedFromNodeTab.label || movedFromNodeTab.id) : 'global'}'`
|
|
18218
|
+
remoteMovedMessage = RED._("diff.type.movedFrom",{id:movedFromLabel});
|
|
17474
18219
|
} else {
|
|
17475
|
-
|
|
18220
|
+
const movedToNodeTab = remoteDiff.newConfig.all[remoteN.z]
|
|
18221
|
+
const movedToLabel = `'${movedToNodeTab ? (movedToNodeTab.label || movedToNodeTab.id) : 'global'}'`
|
|
18222
|
+
remoteMovedMessage = RED._("diff.type.movedTo",{id:movedToLabel});
|
|
17476
18223
|
}
|
|
17477
18224
|
$('<span class="red-ui-diff-status"><i class="fa fa-caret-square-o-right"></i> '+remoteMovedMessage+'</span>').appendTo(remoteNodeDiv);
|
|
17478
18225
|
}
|
|
@@ -17485,8 +18232,13 @@ RED.diagnostics = (function () {
|
|
|
17485
18232
|
if (remoteDiff.newConfig.all[node.id].z !== node.z) {
|
|
17486
18233
|
remoteNodeDiv.addClass("red-ui-diff-empty");
|
|
17487
18234
|
} else {
|
|
17488
|
-
|
|
17489
|
-
|
|
18235
|
+
if (remoteDiff.positionChanged[node.id]) {
|
|
18236
|
+
remoteNodeDiv.addClass("red-ui-diff-status-moved");
|
|
18237
|
+
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.moved"></span></span>').appendTo(remoteNodeDiv);
|
|
18238
|
+
} else {
|
|
18239
|
+
remoteNodeDiv.addClass("red-ui-diff-status-changed");
|
|
18240
|
+
$('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(remoteNodeDiv);
|
|
18241
|
+
}
|
|
17490
18242
|
}
|
|
17491
18243
|
} else {
|
|
17492
18244
|
if (remoteDiff.newConfig.all[node.id].z !== node.z) {
|
|
@@ -17612,7 +18364,7 @@ RED.diagnostics = (function () {
|
|
|
17612
18364
|
$("<td>",{class:"red-ui-diff-list-cell-label"}).text("position").appendTo(row);
|
|
17613
18365
|
localCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-local"}).appendTo(row);
|
|
17614
18366
|
if (localNode) {
|
|
17615
|
-
localCell.addClass("red-ui-diff-status-"+(localChanged?"
|
|
18367
|
+
localCell.addClass("red-ui-diff-status-"+(localChanged?"moved":"unchanged"));
|
|
17616
18368
|
$('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
|
|
17617
18369
|
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell);
|
|
17618
18370
|
var localPosition = {x:localNode.x,y:localNode.y};
|
|
@@ -17637,7 +18389,7 @@ RED.diagnostics = (function () {
|
|
|
17637
18389
|
|
|
17638
18390
|
if (remoteNode !== undefined) {
|
|
17639
18391
|
remoteCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-remote"}).appendTo(row);
|
|
17640
|
-
remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"
|
|
18392
|
+
remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"moved":"unchanged"));
|
|
17641
18393
|
if (remoteNode) {
|
|
17642
18394
|
$('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
|
|
17643
18395
|
element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell);
|
|
@@ -17923,11 +18675,11 @@ RED.diagnostics = (function () {
|
|
|
17923
18675
|
// var diff = generateDiff(originalFlow,nns);
|
|
17924
18676
|
// showDiff(diff);
|
|
17925
18677
|
// }
|
|
17926
|
-
function showRemoteDiff(diff) {
|
|
17927
|
-
if (diff
|
|
17928
|
-
getRemoteDiff(showRemoteDiff);
|
|
18678
|
+
function showRemoteDiff(diff, options = {}) {
|
|
18679
|
+
if (!diff) {
|
|
18680
|
+
getRemoteDiff((remoteDiff) => showRemoteDiff(remoteDiff, options));
|
|
17929
18681
|
} else {
|
|
17930
|
-
showDiff(diff,{mode:'merge'});
|
|
18682
|
+
showDiff(diff,{...options, mode:'merge'});
|
|
17931
18683
|
}
|
|
17932
18684
|
}
|
|
17933
18685
|
function parseNodes(nodeList) {
|
|
@@ -17968,23 +18720,53 @@ RED.diagnostics = (function () {
|
|
|
17968
18720
|
}
|
|
17969
18721
|
}
|
|
17970
18722
|
function generateDiff(currentNodes,newNodes) {
|
|
17971
|
-
|
|
17972
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
17975
|
-
|
|
17976
|
-
|
|
18723
|
+
const currentConfig = parseNodes(currentNodes);
|
|
18724
|
+
const newConfig = parseNodes(newNodes);
|
|
18725
|
+
const added = {};
|
|
18726
|
+
const deleted = {};
|
|
18727
|
+
const changed = {};
|
|
18728
|
+
const positionChanged = {};
|
|
18729
|
+
const moved = {};
|
|
17977
18730
|
|
|
17978
18731
|
Object.keys(currentConfig.all).forEach(function(id) {
|
|
17979
|
-
|
|
18732
|
+
const node = RED.nodes.workspace(id)||RED.nodes.subflow(id)||RED.nodes.node(id);
|
|
17980
18733
|
if (!newConfig.all.hasOwnProperty(id)) {
|
|
17981
18734
|
deleted[id] = true;
|
|
17982
|
-
|
|
18735
|
+
return
|
|
18736
|
+
}
|
|
18737
|
+
const currentConfigJSON = JSON.stringify(currentConfig.all[id])
|
|
18738
|
+
const newConfigJSON = JSON.stringify(newConfig.all[id])
|
|
18739
|
+
|
|
18740
|
+
if (currentConfigJSON !== newConfigJSON) {
|
|
17983
18741
|
changed[id] = true;
|
|
17984
|
-
|
|
17985
18742
|
if (currentConfig.all[id].z !== newConfig.all[id].z) {
|
|
17986
18743
|
moved[id] = true;
|
|
18744
|
+
} else if (
|
|
18745
|
+
currentConfig.all[id].x !== newConfig.all[id].x ||
|
|
18746
|
+
currentConfig.all[id].y !== newConfig.all[id].y ||
|
|
18747
|
+
currentConfig.all[id].w !== newConfig.all[id].w ||
|
|
18748
|
+
currentConfig.all[id].h !== newConfig.all[id].h
|
|
18749
|
+
) {
|
|
18750
|
+
// This node's position on its parent has changed. We want to
|
|
18751
|
+
// check if this is the *only* change for this given node
|
|
18752
|
+
const currentNodeClone = JSON.parse(currentConfigJSON)
|
|
18753
|
+
const newNodeClone = JSON.parse(newConfigJSON)
|
|
18754
|
+
|
|
18755
|
+
delete currentNodeClone.x
|
|
18756
|
+
delete currentNodeClone.y
|
|
18757
|
+
delete currentNodeClone.w
|
|
18758
|
+
delete currentNodeClone.h
|
|
18759
|
+
delete newNodeClone.x
|
|
18760
|
+
delete newNodeClone.y
|
|
18761
|
+
delete newNodeClone.w
|
|
18762
|
+
delete newNodeClone.h
|
|
18763
|
+
|
|
18764
|
+
if (JSON.stringify(currentNodeClone) === JSON.stringify(newNodeClone)) {
|
|
18765
|
+
// Only the position has changed - everything else is the same
|
|
18766
|
+
positionChanged[id] = true
|
|
18767
|
+
}
|
|
17987
18768
|
}
|
|
18769
|
+
|
|
17988
18770
|
}
|
|
17989
18771
|
});
|
|
17990
18772
|
Object.keys(newConfig.all).forEach(function(id) {
|
|
@@ -17993,13 +18775,14 @@ RED.diagnostics = (function () {
|
|
|
17993
18775
|
}
|
|
17994
18776
|
});
|
|
17995
18777
|
|
|
17996
|
-
|
|
17997
|
-
currentConfig
|
|
17998
|
-
newConfig
|
|
17999
|
-
added
|
|
18000
|
-
deleted
|
|
18001
|
-
changed
|
|
18002
|
-
|
|
18778
|
+
const diff = {
|
|
18779
|
+
currentConfig,
|
|
18780
|
+
newConfig,
|
|
18781
|
+
added,
|
|
18782
|
+
deleted,
|
|
18783
|
+
changed,
|
|
18784
|
+
positionChanged,
|
|
18785
|
+
moved
|
|
18003
18786
|
};
|
|
18004
18787
|
return diff;
|
|
18005
18788
|
}
|
|
@@ -18064,12 +18847,14 @@ RED.diagnostics = (function () {
|
|
|
18064
18847
|
return diff;
|
|
18065
18848
|
}
|
|
18066
18849
|
|
|
18067
|
-
function showDiff(diff,options) {
|
|
18850
|
+
function showDiff(diff, options) {
|
|
18068
18851
|
if (diffVisible) {
|
|
18069
18852
|
return;
|
|
18070
18853
|
}
|
|
18071
18854
|
options = options || {};
|
|
18072
18855
|
var mode = options.mode || 'merge';
|
|
18856
|
+
|
|
18857
|
+
options.hidePositionChanges = true
|
|
18073
18858
|
|
|
18074
18859
|
var localDiff = diff.localDiff;
|
|
18075
18860
|
var remoteDiff = diff.remoteDiff;
|
|
@@ -18139,6 +18924,9 @@ RED.diagnostics = (function () {
|
|
|
18139
18924
|
if (!$("#red-ui-diff-view-diff-merge").hasClass('disabled')) {
|
|
18140
18925
|
refreshConflictHeader(diff);
|
|
18141
18926
|
mergeDiff(diff);
|
|
18927
|
+
if (options.onmerge) {
|
|
18928
|
+
options.onmerge()
|
|
18929
|
+
}
|
|
18142
18930
|
RED.tray.close();
|
|
18143
18931
|
}
|
|
18144
18932
|
}
|
|
@@ -18169,6 +18957,7 @@ RED.diagnostics = (function () {
|
|
|
18169
18957
|
var newConfig = [];
|
|
18170
18958
|
var node;
|
|
18171
18959
|
var nodeChangedStates = {};
|
|
18960
|
+
var nodeMovedStates = {};
|
|
18172
18961
|
var localChangedStates = {};
|
|
18173
18962
|
for (id in localDiff.newConfig.all) {
|
|
18174
18963
|
if (localDiff.newConfig.all.hasOwnProperty(id)) {
|
|
@@ -18176,12 +18965,14 @@ RED.diagnostics = (function () {
|
|
|
18176
18965
|
if (resolutions[id] === 'local') {
|
|
18177
18966
|
if (node) {
|
|
18178
18967
|
nodeChangedStates[id] = node.changed;
|
|
18968
|
+
nodeMovedStates[id] = node.moved;
|
|
18179
18969
|
}
|
|
18180
18970
|
newConfig.push(localDiff.newConfig.all[id]);
|
|
18181
18971
|
} else if (resolutions[id] === 'remote') {
|
|
18182
18972
|
if (!remoteDiff.deleted[id] && remoteDiff.newConfig.all.hasOwnProperty(id)) {
|
|
18183
18973
|
if (node) {
|
|
18184
18974
|
nodeChangedStates[id] = node.changed;
|
|
18975
|
+
nodeMovedStates[id] = node.moved;
|
|
18185
18976
|
}
|
|
18186
18977
|
localChangedStates[id] = 1;
|
|
18187
18978
|
newConfig.push(remoteDiff.newConfig.all[id]);
|
|
@@ -18205,8 +18996,9 @@ RED.diagnostics = (function () {
|
|
|
18205
18996
|
}
|
|
18206
18997
|
return {
|
|
18207
18998
|
config: newConfig,
|
|
18208
|
-
nodeChangedStates
|
|
18209
|
-
|
|
18999
|
+
nodeChangedStates,
|
|
19000
|
+
nodeMovedStates,
|
|
19001
|
+
localChangedStates
|
|
18210
19002
|
}
|
|
18211
19003
|
}
|
|
18212
19004
|
|
|
@@ -18217,6 +19009,7 @@ RED.diagnostics = (function () {
|
|
|
18217
19009
|
|
|
18218
19010
|
var newConfig = appliedDiff.config;
|
|
18219
19011
|
var nodeChangedStates = appliedDiff.nodeChangedStates;
|
|
19012
|
+
var nodeMovedStates = appliedDiff.nodeMovedStates;
|
|
18220
19013
|
var localChangedStates = appliedDiff.localChangedStates;
|
|
18221
19014
|
|
|
18222
19015
|
var isDirty = RED.nodes.dirty();
|
|
@@ -18225,33 +19018,56 @@ RED.diagnostics = (function () {
|
|
|
18225
19018
|
t:"replace",
|
|
18226
19019
|
config: RED.nodes.createCompleteNodeSet(),
|
|
18227
19020
|
changed: nodeChangedStates,
|
|
19021
|
+
moved: nodeMovedStates,
|
|
19022
|
+
complete: true,
|
|
18228
19023
|
dirty: isDirty,
|
|
18229
19024
|
rev: RED.nodes.version()
|
|
18230
19025
|
}
|
|
18231
19026
|
|
|
18232
19027
|
RED.history.push(historyEvent);
|
|
18233
19028
|
|
|
18234
|
-
var originalFlow = RED.nodes.originalFlow();
|
|
18235
|
-
// originalFlow is what the editor
|
|
18236
|
-
// - add any newly added nodes from remote diff as they are now part of the record
|
|
18237
|
-
for (var id in diff.remoteDiff.added) {
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
}
|
|
19029
|
+
// var originalFlow = RED.nodes.originalFlow();
|
|
19030
|
+
// // originalFlow is what the editor thinks it loaded
|
|
19031
|
+
// // - add any newly added nodes from remote diff as they are now part of the record
|
|
19032
|
+
// for (var id in diff.remoteDiff.added) {
|
|
19033
|
+
// if (diff.remoteDiff.added.hasOwnProperty(id)) {
|
|
19034
|
+
// if (diff.remoteDiff.newConfig.all.hasOwnProperty(id)) {
|
|
19035
|
+
// originalFlow.push(JSON.parse(JSON.stringify(diff.remoteDiff.newConfig.all[id])));
|
|
19036
|
+
// }
|
|
19037
|
+
// }
|
|
19038
|
+
// }
|
|
18244
19039
|
|
|
18245
19040
|
RED.nodes.clear();
|
|
18246
19041
|
var imported = RED.nodes.import(newConfig);
|
|
18247
19042
|
|
|
18248
|
-
// Restore the original flow so subsequent merge resolutions can properly
|
|
18249
|
-
// identify new-vs-old
|
|
18250
|
-
RED.nodes.originalFlow(originalFlow);
|
|
19043
|
+
// // Restore the original flow so subsequent merge resolutions can properly
|
|
19044
|
+
// // identify new-vs-old
|
|
19045
|
+
// RED.nodes.originalFlow(originalFlow);
|
|
19046
|
+
|
|
19047
|
+
// Clear all change flags from the import
|
|
19048
|
+
RED.nodes.dirty(false);
|
|
19049
|
+
|
|
19050
|
+
const flowsToLock = new Set()
|
|
19051
|
+
function ensureUnlocked(id) {
|
|
19052
|
+
const flow = id && (RED.nodes.workspace(id) || RED.nodes.subflow(id) || null);
|
|
19053
|
+
const isLocked = flow ? flow.locked : false;
|
|
19054
|
+
if (flow && isLocked) {
|
|
19055
|
+
flow.locked = false;
|
|
19056
|
+
flowsToLock.add(flow)
|
|
19057
|
+
}
|
|
19058
|
+
}
|
|
18251
19059
|
imported.nodes.forEach(function(n) {
|
|
18252
|
-
if (nodeChangedStates[n.id]
|
|
19060
|
+
if (nodeChangedStates[n.id]) {
|
|
19061
|
+
ensureUnlocked(n.z)
|
|
18253
19062
|
n.changed = true;
|
|
18254
19063
|
}
|
|
19064
|
+
if (nodeMovedStates[n.id]) {
|
|
19065
|
+
ensureUnlocked(n.z)
|
|
19066
|
+
n.moved = true;
|
|
19067
|
+
}
|
|
19068
|
+
})
|
|
19069
|
+
flowsToLock.forEach(flow => {
|
|
19070
|
+
flow.locked = true
|
|
18255
19071
|
})
|
|
18256
19072
|
|
|
18257
19073
|
RED.nodes.version(diff.remoteDiff.rev);
|
|
@@ -19920,10 +20736,6 @@ RED.keyboard = (function() {
|
|
|
19920
20736
|
}
|
|
19921
20737
|
|
|
19922
20738
|
function init(done) {
|
|
19923
|
-
if (!RED.user.hasPermission("settings.write")) {
|
|
19924
|
-
RED.notify(RED._("user.errors.settings"),"error");
|
|
19925
|
-
return;
|
|
19926
|
-
}
|
|
19927
20739
|
RED.userSettings.add({
|
|
19928
20740
|
id:'envvar',
|
|
19929
20741
|
title: RED._("env-var.environment"),
|
|
@@ -20315,11 +21127,17 @@ RED.workspaces = (function() {
|
|
|
20315
21127
|
RED.sidebar.config.refresh();
|
|
20316
21128
|
RED.view.focus();
|
|
20317
21129
|
},
|
|
20318
|
-
onclick: function(tab) {
|
|
20319
|
-
if
|
|
20320
|
-
|
|
21130
|
+
onclick: function(tab, evt) {
|
|
21131
|
+
if(evt.which === 2) {
|
|
21132
|
+
evt.preventDefault();
|
|
21133
|
+
evt.stopPropagation();
|
|
21134
|
+
RED.actions.invoke("core:hide-flow", tab)
|
|
21135
|
+
} else {
|
|
21136
|
+
if (tab.id !== activeWorkspace) {
|
|
21137
|
+
addToViewStack(activeWorkspace);
|
|
21138
|
+
}
|
|
21139
|
+
RED.view.focus();
|
|
20321
21140
|
}
|
|
20322
|
-
RED.view.focus();
|
|
20323
21141
|
},
|
|
20324
21142
|
ondblclick: function(tab) {
|
|
20325
21143
|
if (tab.type != "subflow") {
|
|
@@ -20357,6 +21175,7 @@ RED.workspaces = (function() {
|
|
|
20357
21175
|
if (tab.type === "tab") {
|
|
20358
21176
|
workspaceTabCount--;
|
|
20359
21177
|
} else {
|
|
21178
|
+
RED.events.emit("workspace:close",{workspace: tab.id})
|
|
20360
21179
|
hideStack.push(tab.id);
|
|
20361
21180
|
}
|
|
20362
21181
|
RED.menu.setDisabled("menu-item-workspace-delete",activeWorkspace === 0 || workspaceTabCount <= 1);
|
|
@@ -20447,6 +21266,11 @@ RED.workspaces = (function() {
|
|
|
20447
21266
|
createWorkspaceTabs();
|
|
20448
21267
|
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
|
20449
21268
|
|
|
21269
|
+
RED.events.on("workspace:clear", () => {
|
|
21270
|
+
// Reset the index used to generate new flow names
|
|
21271
|
+
workspaceIndex = 0
|
|
21272
|
+
})
|
|
21273
|
+
|
|
20450
21274
|
RED.actions.add("core:show-next-tab",function() {
|
|
20451
21275
|
var oldActive = activeWorkspace;
|
|
20452
21276
|
workspace_tabs.nextTab();
|
|
@@ -20613,6 +21437,9 @@ RED.workspaces = (function() {
|
|
|
20613
21437
|
RED.events.on("flows:change", (ws) => {
|
|
20614
21438
|
$("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
|
|
20615
21439
|
})
|
|
21440
|
+
RED.events.on("subflows:change", (ws) => {
|
|
21441
|
+
$("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
|
|
21442
|
+
})
|
|
20616
21443
|
|
|
20617
21444
|
hideWorkspace();
|
|
20618
21445
|
}
|
|
@@ -21564,120 +22391,128 @@ RED.view = (function() {
|
|
|
21564
22391
|
}
|
|
21565
22392
|
d3.event = event;
|
|
21566
22393
|
var selected_tool = $(ui.draggable[0]).attr("data-palette-type");
|
|
21567
|
-
|
|
21568
|
-
|
|
21569
|
-
|
|
21570
|
-
|
|
21571
|
-
|
|
21572
|
-
|
|
22394
|
+
try {
|
|
22395
|
+
var result = createNode(selected_tool);
|
|
22396
|
+
if (!result) {
|
|
22397
|
+
return;
|
|
22398
|
+
}
|
|
22399
|
+
var historyEvent = result.historyEvent;
|
|
22400
|
+
var nn = RED.nodes.add(result.node);
|
|
21573
22401
|
|
|
21574
|
-
|
|
21575
|
-
|
|
21576
|
-
|
|
21577
|
-
|
|
22402
|
+
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
|
22403
|
+
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
|
|
22404
|
+
nn.l = showLabel;
|
|
22405
|
+
}
|
|
21578
22406
|
|
|
21579
|
-
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
22407
|
+
var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0));
|
|
22408
|
+
var helperWidth = ui.helper.width();
|
|
22409
|
+
var helperHeight = ui.helper.height();
|
|
22410
|
+
var mousePos = d3.touches(this)[0]||d3.mouse(this);
|
|
21583
22411
|
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
|
|
21593
|
-
|
|
21594
|
-
|
|
21595
|
-
|
|
22412
|
+
try {
|
|
22413
|
+
var isLink = (nn.type === "link in" || nn.type === "link out")
|
|
22414
|
+
var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink;
|
|
22415
|
+
|
|
22416
|
+
var label = RED.utils.getNodeLabel(nn, nn.type);
|
|
22417
|
+
var labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
|
22418
|
+
if (hideLabel) {
|
|
22419
|
+
nn.w = node_height;
|
|
22420
|
+
nn.h = Math.max(node_height,(nn.outputs || 0) * 15);
|
|
22421
|
+
} else {
|
|
22422
|
+
nn.w = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(nn._def.inputs>0?7:0))/20)) );
|
|
22423
|
+
nn.h = Math.max(6+24*labelParts.lines.length,(nn.outputs || 0) * 15, 30);
|
|
22424
|
+
}
|
|
22425
|
+
} catch(err) {
|
|
21596
22426
|
}
|
|
21597
|
-
} catch(err) {
|
|
21598
|
-
}
|
|
21599
22427
|
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
|
|
21603
|
-
|
|
22428
|
+
mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]);
|
|
22429
|
+
mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]);
|
|
22430
|
+
mousePos[1] /= scaleFactor;
|
|
22431
|
+
mousePos[0] /= scaleFactor;
|
|
21604
22432
|
|
|
21605
|
-
|
|
21606
|
-
|
|
22433
|
+
nn.x = mousePos[0];
|
|
22434
|
+
nn.y = mousePos[1];
|
|
21607
22435
|
|
|
21608
|
-
|
|
21609
|
-
|
|
21610
|
-
|
|
21611
|
-
|
|
21612
|
-
|
|
21613
|
-
|
|
21614
|
-
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
if (snapGrid) {
|
|
21626
|
-
var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
|
|
21627
|
-
nn.x -= gridOffset.x;
|
|
21628
|
-
nn.y -= gridOffset.y;
|
|
21629
|
-
}
|
|
22436
|
+
var minX = nn.w/2 -5;
|
|
22437
|
+
if (nn.x < minX) {
|
|
22438
|
+
nn.x = minX;
|
|
22439
|
+
}
|
|
22440
|
+
var minY = nn.h/2 -5;
|
|
22441
|
+
if (nn.y < minY) {
|
|
22442
|
+
nn.y = minY;
|
|
22443
|
+
}
|
|
22444
|
+
var maxX = space_width -nn.w/2 +5;
|
|
22445
|
+
if (nn.x > maxX) {
|
|
22446
|
+
nn.x = maxX;
|
|
22447
|
+
}
|
|
22448
|
+
var maxY = space_height -nn.h +5;
|
|
22449
|
+
if (nn.y > maxY) {
|
|
22450
|
+
nn.y = maxY;
|
|
22451
|
+
}
|
|
21630
22452
|
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
22453
|
+
if (snapGrid) {
|
|
22454
|
+
var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
|
|
22455
|
+
nn.x -= gridOffset.x;
|
|
22456
|
+
nn.y -= gridOffset.y;
|
|
22457
|
+
}
|
|
21635
22458
|
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
var oldY = group.y;
|
|
21640
|
-
RED.group.addToGroup(group, nn);
|
|
21641
|
-
var moveEvent = null;
|
|
21642
|
-
if ((group.x !== oldX) ||
|
|
21643
|
-
(group.y !== oldY)) {
|
|
21644
|
-
moveEvent = {
|
|
21645
|
-
t: "move",
|
|
21646
|
-
nodes: [{n: group,
|
|
21647
|
-
ox: oldX, oy: oldY,
|
|
21648
|
-
dx: group.x -oldX,
|
|
21649
|
-
dy: group.y -oldY}],
|
|
21650
|
-
dirty: true
|
|
21651
|
-
};
|
|
22459
|
+
var linkToSplice = $(ui.helper).data("splice");
|
|
22460
|
+
if (linkToSplice) {
|
|
22461
|
+
spliceLink(linkToSplice, nn, historyEvent)
|
|
21652
22462
|
}
|
|
21653
|
-
historyEvent = {
|
|
21654
|
-
t: 'multi',
|
|
21655
|
-
events: [historyEvent],
|
|
21656
22463
|
|
|
21657
|
-
|
|
21658
|
-
if (
|
|
21659
|
-
|
|
22464
|
+
var group = $(ui.helper).data("group");
|
|
22465
|
+
if (group) {
|
|
22466
|
+
var oldX = group.x;
|
|
22467
|
+
var oldY = group.y;
|
|
22468
|
+
RED.group.addToGroup(group, nn);
|
|
22469
|
+
var moveEvent = null;
|
|
22470
|
+
if ((group.x !== oldX) ||
|
|
22471
|
+
(group.y !== oldY)) {
|
|
22472
|
+
moveEvent = {
|
|
22473
|
+
t: "move",
|
|
22474
|
+
nodes: [{n: group,
|
|
22475
|
+
ox: oldX, oy: oldY,
|
|
22476
|
+
dx: group.x -oldX,
|
|
22477
|
+
dy: group.y -oldY}],
|
|
22478
|
+
dirty: true
|
|
22479
|
+
};
|
|
22480
|
+
}
|
|
22481
|
+
historyEvent = {
|
|
22482
|
+
t: 'multi',
|
|
22483
|
+
events: [historyEvent],
|
|
22484
|
+
|
|
22485
|
+
};
|
|
22486
|
+
if (moveEvent) {
|
|
22487
|
+
historyEvent.events.push(moveEvent)
|
|
22488
|
+
}
|
|
22489
|
+
historyEvent.events.push({
|
|
22490
|
+
t: "addToGroup",
|
|
22491
|
+
group: group,
|
|
22492
|
+
nodes: nn
|
|
22493
|
+
})
|
|
21660
22494
|
}
|
|
21661
|
-
historyEvent.events.push({
|
|
21662
|
-
t: "addToGroup",
|
|
21663
|
-
group: group,
|
|
21664
|
-
nodes: nn
|
|
21665
|
-
})
|
|
21666
|
-
}
|
|
21667
22495
|
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21671
|
-
|
|
21672
|
-
|
|
21673
|
-
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
|
|
21677
|
-
|
|
22496
|
+
RED.history.push(historyEvent);
|
|
22497
|
+
RED.editor.validateNode(nn);
|
|
22498
|
+
RED.nodes.dirty(true);
|
|
22499
|
+
// auto select dropped node - so info shows (if visible)
|
|
22500
|
+
clearSelection();
|
|
22501
|
+
nn.selected = true;
|
|
22502
|
+
movingSet.add(nn);
|
|
22503
|
+
updateActiveNodes();
|
|
22504
|
+
updateSelection();
|
|
22505
|
+
redraw();
|
|
21678
22506
|
|
|
21679
|
-
|
|
21680
|
-
|
|
22507
|
+
if (nn._def.autoedit) {
|
|
22508
|
+
RED.editor.edit(nn);
|
|
22509
|
+
}
|
|
22510
|
+
} catch (error) {
|
|
22511
|
+
if (error.code != "NODE_RED") {
|
|
22512
|
+
RED.notify(RED._("notification.error",{message:error.toString()}),"error");
|
|
22513
|
+
} else {
|
|
22514
|
+
RED.notify(RED._("notification.error",{message:error.message}),"error");
|
|
22515
|
+
}
|
|
21681
22516
|
}
|
|
21682
22517
|
}
|
|
21683
22518
|
});
|
|
@@ -26981,14 +27816,19 @@ RED.view = (function() {
|
|
|
26981
27816
|
function createNode(type, x, y, z) {
|
|
26982
27817
|
const wasDirty = RED.nodes.dirty()
|
|
26983
27818
|
var m = /^subflow:(.+)$/.exec(type);
|
|
26984
|
-
var activeSubflow = z ? RED.nodes.subflow(z) : null;
|
|
27819
|
+
var activeSubflow = (z || RED.workspaces.active()) ? RED.nodes.subflow(z || RED.workspaces.active()) : null;
|
|
27820
|
+
|
|
26985
27821
|
if (activeSubflow && m) {
|
|
26986
27822
|
var subflowId = m[1];
|
|
27823
|
+
let err
|
|
26987
27824
|
if (subflowId === activeSubflow.id) {
|
|
26988
|
-
|
|
27825
|
+
err = new Error(RED._("notification.errors.cannotAddSubflowToItself"))
|
|
27826
|
+
} else if (RED.nodes.subflowContains(m[1], activeSubflow.id)) {
|
|
27827
|
+
err = new Error(RED._("notification.errors.cannotAddCircularReference"))
|
|
26989
27828
|
}
|
|
26990
|
-
if (
|
|
26991
|
-
|
|
27829
|
+
if (err) {
|
|
27830
|
+
err.code = 'NODE_RED'
|
|
27831
|
+
throw err
|
|
26992
27832
|
}
|
|
26993
27833
|
}
|
|
26994
27834
|
|
|
@@ -27377,14 +28217,27 @@ RED.view = (function() {
|
|
|
27377
28217
|
addAnnotation(evt.node.__pendingAnnotation__,evt);
|
|
27378
28218
|
delete evt.node.__pendingAnnotation__;
|
|
27379
28219
|
}
|
|
27380
|
-
|
|
27381
|
-
|
|
27382
|
-
|
|
27383
|
-
|
|
28220
|
+
let badgeRDX = 0;
|
|
28221
|
+
let badgeLDX = 0;
|
|
28222
|
+
|
|
28223
|
+
for (let i=0,l=evt.el.__annotations__.length;i<l;i++) {
|
|
28224
|
+
const annotation = evt.el.__annotations__[i];
|
|
27384
28225
|
if (annotations.hasOwnProperty(annotation.id)) {
|
|
27385
|
-
|
|
27386
|
-
|
|
27387
|
-
|
|
28226
|
+
const opts = annotations[annotation.id];
|
|
28227
|
+
let showAnnotation = true;
|
|
28228
|
+
const isBadge = opts.type === 'badge';
|
|
28229
|
+
if (opts.refresh !== undefined) {
|
|
28230
|
+
let refreshAnnotation = false
|
|
28231
|
+
if (typeof opts.refresh === "string") {
|
|
28232
|
+
refreshAnnotation = !!evt.node[opts.refresh]
|
|
28233
|
+
delete evt.node[opts.refresh]
|
|
28234
|
+
} else if (typeof opts.refresh === "function") {
|
|
28235
|
+
refreshAnnotation = opts.refresh(evnt.node)
|
|
28236
|
+
}
|
|
28237
|
+
if (refreshAnnotation) {
|
|
28238
|
+
refreshAnnotationElement(annotation.id, annotation.node, annotation.element)
|
|
28239
|
+
}
|
|
28240
|
+
}
|
|
27388
28241
|
if (opts.show !== undefined) {
|
|
27389
28242
|
if (typeof opts.show === "string") {
|
|
27390
28243
|
showAnnotation = !!evt.node[opts.show]
|
|
@@ -27397,17 +28250,24 @@ RED.view = (function() {
|
|
|
27397
28250
|
}
|
|
27398
28251
|
if (isBadge) {
|
|
27399
28252
|
if (showAnnotation) {
|
|
27400
|
-
|
|
27401
|
-
|
|
27402
|
-
|
|
27403
|
-
|
|
27404
|
-
|
|
27405
|
-
|
|
27406
|
-
|
|
27407
|
-
|
|
27408
|
-
|
|
27409
|
-
|
|
28253
|
+
const rect = annotation.element.getBoundingClientRect();
|
|
28254
|
+
let annotationX
|
|
28255
|
+
if (!opts.align || opts.align === 'right') {
|
|
28256
|
+
annotationX = evt.node.w - 3 - badgeRDX - rect.width
|
|
28257
|
+
badgeRDX += rect.width + 4;
|
|
28258
|
+
|
|
28259
|
+
} else if (opts.align === 'left') {
|
|
28260
|
+
annotationX = 3 + badgeLDX
|
|
28261
|
+
badgeLDX += rect.width + 4;
|
|
28262
|
+
}
|
|
28263
|
+
annotation.element.setAttribute("transform", "translate("+annotationX+", -8)");
|
|
27410
28264
|
}
|
|
28265
|
+
// } else {
|
|
28266
|
+
// if (showAnnotation) {
|
|
28267
|
+
// var rect = annotation.element.getBoundingClientRect();
|
|
28268
|
+
// annotation.element.setAttribute("transform", "translate("+(3+controlDX)+", -12)");
|
|
28269
|
+
// controlDX += rect.width + 4;
|
|
28270
|
+
// }
|
|
27411
28271
|
}
|
|
27412
28272
|
} else {
|
|
27413
28273
|
annotation.element.parentNode.removeChild(annotation.element);
|
|
@@ -27463,15 +28323,25 @@ RED.view = (function() {
|
|
|
27463
28323
|
annotationGroup.setAttribute("class",opts.class || "");
|
|
27464
28324
|
evt.el.__annotations__.push({
|
|
27465
28325
|
id:id,
|
|
28326
|
+
node: evt.node,
|
|
27466
28327
|
element: annotationGroup
|
|
27467
28328
|
});
|
|
27468
|
-
|
|
28329
|
+
refreshAnnotationElement(id, evt.node, annotationGroup)
|
|
28330
|
+
evt.el.appendChild(annotationGroup);
|
|
28331
|
+
}
|
|
28332
|
+
|
|
28333
|
+
function refreshAnnotationElement(id, node, annotationGroup) {
|
|
28334
|
+
const opts = annotations[id];
|
|
28335
|
+
const annotation = opts.element(node);
|
|
27469
28336
|
if (opts.tooltip) {
|
|
27470
|
-
annotation.addEventListener("mouseenter", getAnnotationMouseEnter(annotation,
|
|
28337
|
+
annotation.addEventListener("mouseenter", getAnnotationMouseEnter(annotation, node, opts.tooltip));
|
|
27471
28338
|
annotation.addEventListener("mouseleave", annotationMouseLeave);
|
|
27472
28339
|
}
|
|
28340
|
+
if (annotationGroup.hasChildNodes()) {
|
|
28341
|
+
annotationGroup.removeChild(annotationGroup.firstChild)
|
|
28342
|
+
}
|
|
27473
28343
|
annotationGroup.appendChild(annotation);
|
|
27474
|
-
|
|
28344
|
+
|
|
27475
28345
|
}
|
|
27476
28346
|
|
|
27477
28347
|
|
|
@@ -29427,6 +30297,10 @@ RED.palette = (function() {
|
|
|
29427
30297
|
var categoryContainers = {};
|
|
29428
30298
|
var sidebarControls;
|
|
29429
30299
|
|
|
30300
|
+
let paletteState = { filter: "", collapsed: [] };
|
|
30301
|
+
|
|
30302
|
+
let filterRefreshTimeout
|
|
30303
|
+
|
|
29430
30304
|
function createCategory(originalCategory,rootCategory,category,ns) {
|
|
29431
30305
|
if ($("#red-ui-palette-base-category-"+rootCategory).length === 0) {
|
|
29432
30306
|
createCategoryContainer(originalCategory,rootCategory, ns+":palette.label."+rootCategory);
|
|
@@ -29452,20 +30326,57 @@ RED.palette = (function() {
|
|
|
29452
30326
|
catDiv.data('label',label);
|
|
29453
30327
|
categoryContainers[category] = {
|
|
29454
30328
|
container: catDiv,
|
|
29455
|
-
|
|
30329
|
+
hide: function (instant) {
|
|
30330
|
+
if (instant) {
|
|
30331
|
+
catDiv.hide()
|
|
30332
|
+
} else {
|
|
30333
|
+
catDiv.slideUp()
|
|
30334
|
+
}
|
|
30335
|
+
},
|
|
30336
|
+
show: function () {
|
|
30337
|
+
catDiv.show()
|
|
30338
|
+
},
|
|
30339
|
+
isOpen: function () {
|
|
30340
|
+
return !!catDiv.hasClass("red-ui-palette-open")
|
|
30341
|
+
},
|
|
30342
|
+
getNodeCount: function (visibleOnly) {
|
|
30343
|
+
const nodes = catDiv.find(".red-ui-palette-node")
|
|
30344
|
+
if (visibleOnly) {
|
|
30345
|
+
return nodes.filter(function() { return $(this).css('display') !== 'none'}).length
|
|
30346
|
+
} else {
|
|
30347
|
+
return nodes.length
|
|
30348
|
+
}
|
|
30349
|
+
},
|
|
30350
|
+
close: function(instant, skipSaveState) {
|
|
29456
30351
|
catDiv.removeClass("red-ui-palette-open");
|
|
29457
30352
|
catDiv.addClass("red-ui-palette-closed");
|
|
29458
|
-
|
|
30353
|
+
if (instant) {
|
|
30354
|
+
$("#red-ui-palette-base-category-"+category).hide();
|
|
30355
|
+
} else {
|
|
30356
|
+
$("#red-ui-palette-base-category-"+category).slideUp();
|
|
30357
|
+
}
|
|
29459
30358
|
$("#red-ui-palette-header-"+category+" i").removeClass("expanded");
|
|
30359
|
+
if (!skipSaveState) {
|
|
30360
|
+
if (!paletteState.collapsed.includes(category)) {
|
|
30361
|
+
paletteState.collapsed.push(category);
|
|
30362
|
+
savePaletteState();
|
|
30363
|
+
}
|
|
30364
|
+
}
|
|
29460
30365
|
},
|
|
29461
|
-
open: function() {
|
|
30366
|
+
open: function(skipSaveState) {
|
|
29462
30367
|
catDiv.addClass("red-ui-palette-open");
|
|
29463
30368
|
catDiv.removeClass("red-ui-palette-closed");
|
|
29464
30369
|
$("#red-ui-palette-base-category-"+category).slideDown();
|
|
29465
30370
|
$("#red-ui-palette-header-"+category+" i").addClass("expanded");
|
|
30371
|
+
if (!skipSaveState) {
|
|
30372
|
+
if (paletteState.collapsed.includes(category)) {
|
|
30373
|
+
paletteState.collapsed.splice(paletteState.collapsed.indexOf(category), 1);
|
|
30374
|
+
savePaletteState();
|
|
30375
|
+
}
|
|
30376
|
+
}
|
|
29466
30377
|
},
|
|
29467
30378
|
toggle: function() {
|
|
29468
|
-
if (
|
|
30379
|
+
if (categoryContainers[category].isOpen()) {
|
|
29469
30380
|
categoryContainers[category].close();
|
|
29470
30381
|
} else {
|
|
29471
30382
|
categoryContainers[category].open();
|
|
@@ -29807,8 +30718,16 @@ RED.palette = (function() {
|
|
|
29807
30718
|
|
|
29808
30719
|
var categoryNode = $("#red-ui-palette-container-"+rootCategory);
|
|
29809
30720
|
if (categoryNode.find(".red-ui-palette-node").length === 1) {
|
|
29810
|
-
|
|
30721
|
+
if (!paletteState?.collapsed?.includes(rootCategory)) {
|
|
30722
|
+
categoryContainers[rootCategory].open();
|
|
30723
|
+
} else {
|
|
30724
|
+
categoryContainers[rootCategory].close(true);
|
|
30725
|
+
}
|
|
29811
30726
|
}
|
|
30727
|
+
clearTimeout(filterRefreshTimeout)
|
|
30728
|
+
filterRefreshTimeout = setTimeout(() => {
|
|
30729
|
+
refreshFilter()
|
|
30730
|
+
}, 200)
|
|
29812
30731
|
|
|
29813
30732
|
}
|
|
29814
30733
|
}
|
|
@@ -29908,7 +30827,8 @@ RED.palette = (function() {
|
|
|
29908
30827
|
paletteNode.css("backgroundColor", sf.color);
|
|
29909
30828
|
}
|
|
29910
30829
|
|
|
29911
|
-
function
|
|
30830
|
+
function refreshFilter() {
|
|
30831
|
+
const val = $("#red-ui-palette-search input").val()
|
|
29912
30832
|
var re = new RegExp(val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),'i');
|
|
29913
30833
|
$("#red-ui-palette-container .red-ui-palette-node").each(function(i,el) {
|
|
29914
30834
|
var currentLabel = $(el).attr("data-palette-label");
|
|
@@ -29920,16 +30840,26 @@ RED.palette = (function() {
|
|
|
29920
30840
|
}
|
|
29921
30841
|
});
|
|
29922
30842
|
|
|
29923
|
-
for (
|
|
30843
|
+
for (let category in categoryContainers) {
|
|
29924
30844
|
if (categoryContainers.hasOwnProperty(category)) {
|
|
29925
|
-
|
|
29926
|
-
|
|
29927
|
-
|
|
29928
|
-
categoryContainers[category].close();
|
|
29929
|
-
categoryContainers[category].container.slideUp();
|
|
30845
|
+
const categorySection = categoryContainers[category]
|
|
30846
|
+
if (categorySection.getNodeCount(true) === 0) {
|
|
30847
|
+
categorySection.hide()
|
|
29930
30848
|
} else {
|
|
29931
|
-
|
|
29932
|
-
|
|
30849
|
+
categorySection.show()
|
|
30850
|
+
if (val) {
|
|
30851
|
+
// There is a filter being applied and it has matched
|
|
30852
|
+
// something in this category - show the contents
|
|
30853
|
+
categorySection.open(true)
|
|
30854
|
+
} else {
|
|
30855
|
+
// No filter. Only show the category if it isn't in lastState
|
|
30856
|
+
if (!paletteState.collapsed.includes(category)) {
|
|
30857
|
+
categorySection.open(true)
|
|
30858
|
+
} else if (categorySection.isOpen()) {
|
|
30859
|
+
// This section should be collapsed but isn't - so make it so
|
|
30860
|
+
categorySection.close(true, true)
|
|
30861
|
+
}
|
|
30862
|
+
}
|
|
29933
30863
|
}
|
|
29934
30864
|
}
|
|
29935
30865
|
}
|
|
@@ -29945,6 +30875,9 @@ RED.palette = (function() {
|
|
|
29945
30875
|
|
|
29946
30876
|
$("#red-ui-palette > .red-ui-palette-spinner").show();
|
|
29947
30877
|
|
|
30878
|
+
RED.events.on('logout', function () {
|
|
30879
|
+
RED.settings.removeLocal('palette-state')
|
|
30880
|
+
})
|
|
29948
30881
|
|
|
29949
30882
|
RED.events.on('registry:node-type-added', function(nodeType) {
|
|
29950
30883
|
var def = RED.nodes.getType(nodeType);
|
|
@@ -29988,14 +30921,14 @@ RED.palette = (function() {
|
|
|
29988
30921
|
|
|
29989
30922
|
RED.events.on("subflows:change",refreshSubflow);
|
|
29990
30923
|
|
|
29991
|
-
|
|
29992
|
-
|
|
29993
30924
|
$("#red-ui-palette-search input").searchBox({
|
|
29994
30925
|
delay: 100,
|
|
29995
30926
|
change: function() {
|
|
29996
|
-
|
|
30927
|
+
refreshFilter();
|
|
30928
|
+
paletteState.filter = $(this).val();
|
|
30929
|
+
savePaletteState();
|
|
29997
30930
|
}
|
|
29998
|
-
})
|
|
30931
|
+
});
|
|
29999
30932
|
|
|
30000
30933
|
sidebarControls = $('<div class="red-ui-sidebar-control-left"><i class="fa fa-chevron-left"></i></div>').appendTo($("#red-ui-palette"));
|
|
30001
30934
|
RED.popover.tooltip(sidebarControls,RED._("keyboard.togglePalette"),"core:toggle-palette");
|
|
@@ -30061,7 +30994,23 @@ RED.palette = (function() {
|
|
|
30061
30994
|
togglePalette(state);
|
|
30062
30995
|
}
|
|
30063
30996
|
});
|
|
30997
|
+
|
|
30998
|
+
try {
|
|
30999
|
+
paletteState = JSON.parse(RED.settings.getLocal("palette-state") || '{"filter":"", "collapsed": []}');
|
|
31000
|
+
if (paletteState.filter) {
|
|
31001
|
+
// Apply the category filter
|
|
31002
|
+
$("#red-ui-palette-search input").searchBox("value", paletteState.filter);
|
|
31003
|
+
}
|
|
31004
|
+
} catch (error) {
|
|
31005
|
+
console.error("Unexpected error loading palette state from localStorage: ", error);
|
|
31006
|
+
}
|
|
31007
|
+
setTimeout(() => {
|
|
31008
|
+
// Lazily tidy up any categories that haven't been reloaded
|
|
31009
|
+
paletteState.collapsed = paletteState.collapsed.filter(category => !!categoryContainers[category])
|
|
31010
|
+
savePaletteState()
|
|
31011
|
+
}, 10000)
|
|
30064
31012
|
}
|
|
31013
|
+
|
|
30065
31014
|
function togglePalette(state) {
|
|
30066
31015
|
if (!state) {
|
|
30067
31016
|
$("#red-ui-main-container").addClass("red-ui-palette-closed");
|
|
@@ -30081,6 +31030,15 @@ RED.palette = (function() {
|
|
|
30081
31030
|
})
|
|
30082
31031
|
return categories;
|
|
30083
31032
|
}
|
|
31033
|
+
|
|
31034
|
+
function savePaletteState() {
|
|
31035
|
+
try {
|
|
31036
|
+
RED.settings.setLocal("palette-state", JSON.stringify(paletteState));
|
|
31037
|
+
} catch (error) {
|
|
31038
|
+
console.error("Unexpected error saving palette state to localStorage: ", error);
|
|
31039
|
+
}
|
|
31040
|
+
}
|
|
31041
|
+
|
|
30084
31042
|
return {
|
|
30085
31043
|
init: init,
|
|
30086
31044
|
add:addNodeType,
|
|
@@ -31570,8 +32528,10 @@ RED.sidebar.help = (function() {
|
|
|
31570
32528
|
|
|
31571
32529
|
function refreshSubflow(sf) {
|
|
31572
32530
|
var item = treeList.treeList('get',"node-type:subflow:"+sf.id);
|
|
31573
|
-
|
|
31574
|
-
|
|
32531
|
+
if (item) {
|
|
32532
|
+
item.subflowLabel = sf._def.label().toLowerCase();
|
|
32533
|
+
item.treeList.replaceElement(getNodeLabel({_def:sf._def,type:sf._def.label()}));
|
|
32534
|
+
}
|
|
31575
32535
|
}
|
|
31576
32536
|
|
|
31577
32537
|
function hideTOC() {
|
|
@@ -32823,7 +33783,7 @@ RED.palette.editor = (function() {
|
|
|
32823
33783
|
}).done(function(data,textStatus,xhr) {
|
|
32824
33784
|
callback();
|
|
32825
33785
|
}).fail(function(xhr,textStatus,err) {
|
|
32826
|
-
callback(xhr);
|
|
33786
|
+
callback(xhr,textStatus,err);
|
|
32827
33787
|
});
|
|
32828
33788
|
}
|
|
32829
33789
|
function removeNodeModule(id,callback) {
|
|
@@ -32938,86 +33898,106 @@ RED.palette.editor = (function() {
|
|
|
32938
33898
|
var moduleInfo = nodeEntries[module].info;
|
|
32939
33899
|
var nodeEntry = nodeEntries[module].elements;
|
|
32940
33900
|
if (nodeEntry) {
|
|
32941
|
-
|
|
32942
|
-
|
|
32943
|
-
|
|
32944
|
-
|
|
32945
|
-
|
|
32946
|
-
|
|
32947
|
-
|
|
32948
|
-
|
|
32949
|
-
|
|
32950
|
-
|
|
32951
|
-
var set = moduleInfo.sets[setName];
|
|
32952
|
-
var setElements = nodeEntry.sets[setName];
|
|
32953
|
-
if (set.err) {
|
|
32954
|
-
errorCount++;
|
|
32955
|
-
var errMessage = set.err;
|
|
32956
|
-
if (set.err.message) {
|
|
32957
|
-
errMessage = set.err.message;
|
|
32958
|
-
} else if (set.err.code) {
|
|
32959
|
-
errMessage = set.err.code;
|
|
32960
|
-
}
|
|
32961
|
-
$("<li>").text(errMessage).appendTo(nodeEntry.errorList);
|
|
32962
|
-
}
|
|
32963
|
-
if (set.enabled) {
|
|
32964
|
-
activeTypeCount += set.types.length;
|
|
32965
|
-
}
|
|
32966
|
-
typeCount += set.types.length;
|
|
32967
|
-
for (var i=0;i<moduleInfo.sets[setName].types.length;i++) {
|
|
32968
|
-
var t = moduleInfo.sets[setName].types[i];
|
|
32969
|
-
inUseCount += (typesInUse[t]||0);
|
|
32970
|
-
var swatch = setElements.swatches[t];
|
|
32971
|
-
if (set.enabled) {
|
|
32972
|
-
var def = RED.nodes.getType(t);
|
|
32973
|
-
if (def && def.color) {
|
|
32974
|
-
swatch.css({background:RED.utils.getNodeColor(t,def)});
|
|
32975
|
-
swatch.css({border: "1px solid "+getContrastingBorder(swatch.css('backgroundColor'))})
|
|
32976
|
-
}
|
|
33901
|
+
if (moduleInfo.plugin) {
|
|
33902
|
+
nodeEntry.enableButton.hide();
|
|
33903
|
+
nodeEntry.removeButton.show();
|
|
33904
|
+
|
|
33905
|
+
let pluginCount = 0;
|
|
33906
|
+
for (let setName in moduleInfo.sets) {
|
|
33907
|
+
if (moduleInfo.sets.hasOwnProperty(setName)) {
|
|
33908
|
+
let set = moduleInfo.sets[setName];
|
|
33909
|
+
if (set.plugins) {
|
|
33910
|
+
pluginCount += set.plugins.length;
|
|
32977
33911
|
}
|
|
32978
33912
|
}
|
|
32979
|
-
|
|
32980
|
-
|
|
33913
|
+
}
|
|
33914
|
+
|
|
33915
|
+
nodeEntry.setCount.text(RED._('palette.editor.pluginCount',{count:pluginCount,label:pluginCount}));
|
|
32981
33916
|
|
|
32982
|
-
|
|
32983
|
-
|
|
32984
|
-
|
|
32985
|
-
|
|
32986
|
-
|
|
33917
|
+
} else {
|
|
33918
|
+
var activeTypeCount = 0;
|
|
33919
|
+
var typeCount = 0;
|
|
33920
|
+
var errorCount = 0;
|
|
33921
|
+
nodeEntry.errorList.empty();
|
|
33922
|
+
nodeEntries[module].totalUseCount = 0;
|
|
33923
|
+
nodeEntries[module].setUseCount = {};
|
|
33924
|
+
|
|
33925
|
+
for (var setName in moduleInfo.sets) {
|
|
33926
|
+
if (moduleInfo.sets.hasOwnProperty(setName)) {
|
|
33927
|
+
var inUseCount = 0;
|
|
33928
|
+
const set = moduleInfo.sets[setName];
|
|
33929
|
+
const setElements = nodeEntry.sets[setName]
|
|
33930
|
+
|
|
33931
|
+
if (set.err) {
|
|
33932
|
+
errorCount++;
|
|
33933
|
+
var errMessage = set.err;
|
|
33934
|
+
if (set.err.message) {
|
|
33935
|
+
errMessage = set.err.message;
|
|
33936
|
+
} else if (set.err.code) {
|
|
33937
|
+
errMessage = set.err.code;
|
|
33938
|
+
}
|
|
33939
|
+
$("<li>").text(errMessage).appendTo(nodeEntry.errorList);
|
|
33940
|
+
}
|
|
32987
33941
|
if (set.enabled) {
|
|
32988
|
-
|
|
32989
|
-
}
|
|
32990
|
-
|
|
33942
|
+
activeTypeCount += set.types.length;
|
|
33943
|
+
}
|
|
33944
|
+
typeCount += set.types.length;
|
|
33945
|
+
for (var i=0;i<moduleInfo.sets[setName].types.length;i++) {
|
|
33946
|
+
var t = moduleInfo.sets[setName].types[i];
|
|
33947
|
+
inUseCount += (typesInUse[t]||0);
|
|
33948
|
+
if (setElements && set.enabled) {
|
|
33949
|
+
var def = RED.nodes.getType(t);
|
|
33950
|
+
if (def && def.color) {
|
|
33951
|
+
setElements.swatches[t].css({background:RED.utils.getNodeColor(t,def)});
|
|
33952
|
+
setElements.swatches[t].css({border: "1px solid "+getContrastingBorder(setElements.swatches[t].css('backgroundColor'))})
|
|
33953
|
+
}
|
|
33954
|
+
}
|
|
33955
|
+
}
|
|
33956
|
+
nodeEntries[module].setUseCount[setName] = inUseCount;
|
|
33957
|
+
nodeEntries[module].totalUseCount += inUseCount;
|
|
33958
|
+
|
|
33959
|
+
if (setElements) {
|
|
33960
|
+
if (inUseCount > 0) {
|
|
33961
|
+
setElements.enableButton.text(RED._('palette.editor.inuse'));
|
|
33962
|
+
setElements.enableButton.addClass('disabled');
|
|
33963
|
+
} else {
|
|
33964
|
+
setElements.enableButton.removeClass('disabled');
|
|
33965
|
+
if (set.enabled) {
|
|
33966
|
+
setElements.enableButton.text(RED._('palette.editor.disable'));
|
|
33967
|
+
} else {
|
|
33968
|
+
setElements.enableButton.text(RED._('palette.editor.enable'));
|
|
33969
|
+
}
|
|
33970
|
+
}
|
|
33971
|
+
setElements.setRow.toggleClass("red-ui-palette-module-set-disabled",!set.enabled);
|
|
32991
33972
|
}
|
|
32992
33973
|
}
|
|
32993
|
-
setElements.setRow.toggleClass("red-ui-palette-module-set-disabled",!set.enabled);
|
|
32994
33974
|
}
|
|
32995
|
-
}
|
|
32996
33975
|
|
|
32997
|
-
|
|
32998
|
-
|
|
32999
|
-
|
|
33000
|
-
|
|
33001
|
-
|
|
33976
|
+
if (errorCount === 0) {
|
|
33977
|
+
nodeEntry.errorRow.hide()
|
|
33978
|
+
} else {
|
|
33979
|
+
nodeEntry.errorRow.show();
|
|
33980
|
+
}
|
|
33002
33981
|
|
|
33003
|
-
|
|
33004
|
-
|
|
33982
|
+
var nodeCount = (activeTypeCount === typeCount)?typeCount:activeTypeCount+" / "+typeCount;
|
|
33983
|
+
nodeEntry.setCount.text(RED._('palette.editor.nodeCount',{count:typeCount,label:nodeCount}));
|
|
33005
33984
|
|
|
33006
|
-
|
|
33007
|
-
|
|
33008
|
-
|
|
33009
|
-
|
|
33010
|
-
} else {
|
|
33011
|
-
nodeEntry.enableButton.removeClass('disabled');
|
|
33012
|
-
if (moduleInfo.local) {
|
|
33013
|
-
nodeEntry.removeButton.css('display', 'inline-block');
|
|
33014
|
-
}
|
|
33015
|
-
if (activeTypeCount === 0) {
|
|
33016
|
-
nodeEntry.enableButton.text(RED._('palette.editor.enableall'));
|
|
33985
|
+
if (nodeEntries[module].totalUseCount > 0) {
|
|
33986
|
+
nodeEntry.enableButton.text(RED._('palette.editor.inuse'));
|
|
33987
|
+
nodeEntry.enableButton.addClass('disabled');
|
|
33988
|
+
nodeEntry.removeButton.hide();
|
|
33017
33989
|
} else {
|
|
33018
|
-
nodeEntry.enableButton.
|
|
33990
|
+
nodeEntry.enableButton.removeClass('disabled');
|
|
33991
|
+
if (moduleInfo.local) {
|
|
33992
|
+
nodeEntry.removeButton.css('display', 'inline-block');
|
|
33993
|
+
}
|
|
33994
|
+
if (activeTypeCount === 0) {
|
|
33995
|
+
nodeEntry.enableButton.text(RED._('palette.editor.enableall'));
|
|
33996
|
+
} else {
|
|
33997
|
+
nodeEntry.enableButton.text(RED._('palette.editor.disableall'));
|
|
33998
|
+
}
|
|
33999
|
+
nodeEntry.container.toggleClass("disabled",(activeTypeCount === 0));
|
|
33019
34000
|
}
|
|
33020
|
-
nodeEntry.container.toggleClass("disabled",(activeTypeCount === 0));
|
|
33021
34001
|
}
|
|
33022
34002
|
}
|
|
33023
34003
|
if (moduleInfo.pending_version) {
|
|
@@ -33368,6 +34348,33 @@ RED.palette.editor = (function() {
|
|
|
33368
34348
|
}
|
|
33369
34349
|
}
|
|
33370
34350
|
})
|
|
34351
|
+
|
|
34352
|
+
RED.events.on("registry:plugin-module-added", function(module) {
|
|
34353
|
+
|
|
34354
|
+
if (!nodeEntries.hasOwnProperty(module)) {
|
|
34355
|
+
nodeEntries[module] = {info:RED.plugins.getModule(module)};
|
|
34356
|
+
var index = [module];
|
|
34357
|
+
for (var s in nodeEntries[module].info.sets) {
|
|
34358
|
+
if (nodeEntries[module].info.sets.hasOwnProperty(s)) {
|
|
34359
|
+
index.push(s);
|
|
34360
|
+
index = index.concat(nodeEntries[module].info.sets[s].types)
|
|
34361
|
+
}
|
|
34362
|
+
}
|
|
34363
|
+
nodeEntries[module].index = index.join(",").toLowerCase();
|
|
34364
|
+
nodeList.editableList('addItem', nodeEntries[module]);
|
|
34365
|
+
} else {
|
|
34366
|
+
_refreshNodeModule(module);
|
|
34367
|
+
}
|
|
34368
|
+
|
|
34369
|
+
for (var i=0;i<filteredList.length;i++) {
|
|
34370
|
+
if (filteredList[i].info.id === module) {
|
|
34371
|
+
var installButton = filteredList[i].elements.installButton;
|
|
34372
|
+
installButton.addClass('disabled');
|
|
34373
|
+
installButton.text(RED._('palette.editor.installed'));
|
|
34374
|
+
break;
|
|
34375
|
+
}
|
|
34376
|
+
}
|
|
34377
|
+
});
|
|
33371
34378
|
}
|
|
33372
34379
|
|
|
33373
34380
|
var settingsPane;
|
|
@@ -33494,6 +34501,7 @@ RED.palette.editor = (function() {
|
|
|
33494
34501
|
errorRow: errorRow,
|
|
33495
34502
|
errorList: errorList,
|
|
33496
34503
|
setCount: setCount,
|
|
34504
|
+
setButton: setButton,
|
|
33497
34505
|
container: container,
|
|
33498
34506
|
shade: shade,
|
|
33499
34507
|
versionSpan: versionSpan,
|
|
@@ -33504,49 +34512,88 @@ RED.palette.editor = (function() {
|
|
|
33504
34512
|
if (container.hasClass('expanded')) {
|
|
33505
34513
|
container.removeClass('expanded');
|
|
33506
34514
|
contentRow.slideUp();
|
|
34515
|
+
setTimeout(() => {
|
|
34516
|
+
contentRow.empty()
|
|
34517
|
+
}, 200)
|
|
34518
|
+
object.elements.sets = {}
|
|
33507
34519
|
} else {
|
|
33508
34520
|
container.addClass('expanded');
|
|
34521
|
+
populateSetList()
|
|
33509
34522
|
contentRow.slideDown();
|
|
33510
34523
|
}
|
|
33511
34524
|
})
|
|
33512
|
-
|
|
33513
|
-
|
|
33514
|
-
|
|
33515
|
-
|
|
33516
|
-
|
|
33517
|
-
|
|
33518
|
-
|
|
33519
|
-
|
|
33520
|
-
|
|
33521
|
-
|
|
33522
|
-
|
|
33523
|
-
|
|
33524
|
-
|
|
33525
|
-
|
|
33526
|
-
|
|
33527
|
-
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
33532
|
-
shade.show();
|
|
33533
|
-
var newState = !currentSet.enabled
|
|
33534
|
-
changeNodeState(set.id,newState,shade,function(xhr){
|
|
33535
|
-
if (xhr) {
|
|
33536
|
-
if (xhr.responseJSON) {
|
|
33537
|
-
RED.notify(RED._('palette.editor.errors.'+(newState?'enable':'disable')+'Failed',{module: id,message:xhr.responseJSON.message}));
|
|
34525
|
+
const populateSetList = function () {
|
|
34526
|
+
var setList = Object.keys(entry.sets)
|
|
34527
|
+
setList.sort(function(A,B) {
|
|
34528
|
+
return A.toLowerCase().localeCompare(B.toLowerCase());
|
|
34529
|
+
});
|
|
34530
|
+
setList.forEach(function(setName) {
|
|
34531
|
+
var set = entry.sets[setName];
|
|
34532
|
+
var setRow = $('<div>',{class:"red-ui-palette-module-set"}).appendTo(contentRow);
|
|
34533
|
+
var buttonGroup = $('<div>',{class:"red-ui-palette-module-set-button-group"}).appendTo(setRow);
|
|
34534
|
+
var typeSwatches = {};
|
|
34535
|
+
let enableButton;
|
|
34536
|
+
if (set.types) {
|
|
34537
|
+
set.types.forEach(function(t) {
|
|
34538
|
+
var typeDiv = $('<div>',{class:"red-ui-palette-module-type"}).appendTo(setRow);
|
|
34539
|
+
typeSwatches[t] = $('<span>',{class:"red-ui-palette-module-type-swatch"}).appendTo(typeDiv);
|
|
34540
|
+
if (set.enabled) {
|
|
34541
|
+
var def = RED.nodes.getType(t);
|
|
34542
|
+
if (def && def.color) {
|
|
34543
|
+
typeSwatches[t].css({background:RED.utils.getNodeColor(t,def)});
|
|
34544
|
+
typeSwatches[t].css({border: "1px solid "+getContrastingBorder(typeSwatches[t].css('backgroundColor'))})
|
|
33538
34545
|
}
|
|
33539
34546
|
}
|
|
33540
|
-
|
|
34547
|
+
$('<span>',{class:"red-ui-palette-module-type-node"}).text(t).appendTo(typeDiv);
|
|
34548
|
+
})
|
|
34549
|
+
enableButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').appendTo(buttonGroup);
|
|
34550
|
+
enableButton.on("click", function(evt) {
|
|
34551
|
+
evt.preventDefault();
|
|
34552
|
+
if (object.setUseCount[setName] === 0) {
|
|
34553
|
+
var currentSet = RED.nodes.registry.getNodeSet(set.id);
|
|
34554
|
+
shade.show();
|
|
34555
|
+
var newState = !currentSet.enabled
|
|
34556
|
+
changeNodeState(set.id,newState,shade,function(xhr){
|
|
34557
|
+
if (xhr) {
|
|
34558
|
+
if (xhr.responseJSON) {
|
|
34559
|
+
RED.notify(RED._('palette.editor.errors.'+(newState?'enable':'disable')+'Failed',{module: id,message:xhr.responseJSON.message}));
|
|
34560
|
+
}
|
|
34561
|
+
}
|
|
34562
|
+
});
|
|
34563
|
+
}
|
|
34564
|
+
})
|
|
34565
|
+
|
|
34566
|
+
if (object.setUseCount[setName] > 0) {
|
|
34567
|
+
enableButton.text(RED._('palette.editor.inuse'));
|
|
34568
|
+
enableButton.addClass('disabled');
|
|
34569
|
+
} else {
|
|
34570
|
+
enableButton.removeClass('disabled');
|
|
34571
|
+
if (set.enabled) {
|
|
34572
|
+
enableButton.text(RED._('palette.editor.disable'));
|
|
34573
|
+
} else {
|
|
34574
|
+
enableButton.text(RED._('palette.editor.enable'));
|
|
34575
|
+
}
|
|
34576
|
+
}
|
|
34577
|
+
setRow.toggleClass("red-ui-palette-module-set-disabled",!set.enabled);
|
|
34578
|
+
|
|
34579
|
+
|
|
34580
|
+
}
|
|
34581
|
+
if (set.plugins) {
|
|
34582
|
+
set.plugins.forEach(function(p) {
|
|
34583
|
+
var typeDiv = $('<div>',{class:"red-ui-palette-module-type"}).appendTo(setRow);
|
|
34584
|
+
// typeSwatches[p.id] = $('<span>',{class:"red-ui-palette-module-type-swatch"}).appendTo(typeDiv);
|
|
34585
|
+
$('<span><i class="fa fa-puzzle-piece" aria-hidden="true"></i> </span>',{class:"red-ui-palette-module-type-swatch"}).appendTo(typeDiv);
|
|
34586
|
+
$('<span>',{class:"red-ui-palette-module-type-node"}).text(p.id).appendTo(typeDiv);
|
|
34587
|
+
})
|
|
33541
34588
|
}
|
|
33542
|
-
})
|
|
33543
34589
|
|
|
33544
|
-
|
|
33545
|
-
|
|
33546
|
-
|
|
33547
|
-
|
|
33548
|
-
|
|
33549
|
-
|
|
34590
|
+
object.elements.sets[set.name] = {
|
|
34591
|
+
setRow: setRow,
|
|
34592
|
+
enableButton: enableButton,
|
|
34593
|
+
swatches: typeSwatches
|
|
34594
|
+
};
|
|
34595
|
+
});
|
|
34596
|
+
}
|
|
33550
34597
|
enableButton.on("click", function(evt) {
|
|
33551
34598
|
evt.preventDefault();
|
|
33552
34599
|
if (object.totalUseCount === 0) {
|
|
@@ -33916,7 +34963,55 @@ RED.palette.editor = (function() {
|
|
|
33916
34963
|
}
|
|
33917
34964
|
}
|
|
33918
34965
|
]
|
|
33919
|
-
});
|
|
34966
|
+
});
|
|
34967
|
+
}
|
|
34968
|
+
} else {
|
|
34969
|
+
// dedicated list management for plugins
|
|
34970
|
+
if (entry.plugin) {
|
|
34971
|
+
|
|
34972
|
+
let e = nodeEntries[entry.name];
|
|
34973
|
+
if (e) {
|
|
34974
|
+
nodeList.editableList('removeItem', e);
|
|
34975
|
+
delete nodeEntries[entry.name];
|
|
34976
|
+
}
|
|
34977
|
+
|
|
34978
|
+
// We assume that a plugin that implements onremove
|
|
34979
|
+
// cleans the editor accordingly of its left-overs.
|
|
34980
|
+
let found_onremove = true;
|
|
34981
|
+
|
|
34982
|
+
let keys = Object.keys(entry.sets);
|
|
34983
|
+
keys.forEach((key) => {
|
|
34984
|
+
let set = entry.sets[key];
|
|
34985
|
+
for (let i=0; i<set.plugins?.length; i++) {
|
|
34986
|
+
let plgn = RED.plugins.getPlugin(set.plugins[i].id);
|
|
34987
|
+
if (plgn && plgn.onremove && typeof plgn.onremove === 'function') {
|
|
34988
|
+
plgn.onremove();
|
|
34989
|
+
} else {
|
|
34990
|
+
if (plgn && plgn.onadd && typeof plgn.onadd === 'function') {
|
|
34991
|
+
// if there's no 'onadd', there shouldn't be any left-overs
|
|
34992
|
+
found_onremove = false;
|
|
34993
|
+
}
|
|
34994
|
+
}
|
|
34995
|
+
}
|
|
34996
|
+
});
|
|
34997
|
+
|
|
34998
|
+
if (!found_onremove) {
|
|
34999
|
+
let removeNotify = RED.notify(RED._("palette.editor.confirm.removePlugin.body",{module:entry.name}),{
|
|
35000
|
+
modal: true,
|
|
35001
|
+
fixed: true,
|
|
35002
|
+
type: 'warning',
|
|
35003
|
+
buttons: [
|
|
35004
|
+
{
|
|
35005
|
+
text: RED._("palette.editor.confirm.button.understood"),
|
|
35006
|
+
class:"primary",
|
|
35007
|
+
click: function(e) {
|
|
35008
|
+
removeNotify.close();
|
|
35009
|
+
}
|
|
35010
|
+
}
|
|
35011
|
+
]
|
|
35012
|
+
});
|
|
35013
|
+
}
|
|
35014
|
+
}
|
|
33920
35015
|
}
|
|
33921
35016
|
})
|
|
33922
35017
|
notification.close();
|
|
@@ -33960,9 +35055,28 @@ RED.palette.editor = (function() {
|
|
|
33960
35055
|
RED.actions.invoke("core:show-event-log");
|
|
33961
35056
|
});
|
|
33962
35057
|
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version);
|
|
33963
|
-
installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr) {
|
|
35058
|
+
installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr, textStatus,err) {
|
|
33964
35059
|
spinner.remove();
|
|
33965
|
-
if (xhr) {
|
|
35060
|
+
if (err && xhr.status === 504) {
|
|
35061
|
+
var notification = RED.notify(RED._("palette.editor.errors.installTimeout"), {
|
|
35062
|
+
modal: true,
|
|
35063
|
+
fixed: true,
|
|
35064
|
+
buttons: [
|
|
35065
|
+
{
|
|
35066
|
+
text: RED._("common.label.close"),
|
|
35067
|
+
click: function() {
|
|
35068
|
+
notification.close();
|
|
35069
|
+
}
|
|
35070
|
+
},{
|
|
35071
|
+
text: RED._("eventLog.view"),
|
|
35072
|
+
click: function() {
|
|
35073
|
+
notification.close();
|
|
35074
|
+
RED.actions.invoke("core:show-event-log");
|
|
35075
|
+
}
|
|
35076
|
+
}
|
|
35077
|
+
]
|
|
35078
|
+
})
|
|
35079
|
+
} else if (xhr) {
|
|
33966
35080
|
if (xhr.responseJSON) {
|
|
33967
35081
|
var notification = RED.notify(RED._('palette.editor.errors.installFailed',{module: entry.id,message:xhr.responseJSON.message}),{
|
|
33968
35082
|
type: 'error',
|
|
@@ -34346,8 +35460,9 @@ RED.editor = (function() {
|
|
|
34346
35460
|
nodeValue = node[property]
|
|
34347
35461
|
}
|
|
34348
35462
|
|
|
34349
|
-
const
|
|
34350
|
-
const
|
|
35463
|
+
const addBtnId = `${prefix}-btn-${property}-add`;
|
|
35464
|
+
const editBtnId = `${prefix}-btn-${property}-edit`;
|
|
35465
|
+
const selectId = prefix + '-' + property;
|
|
34351
35466
|
const input = $(`#${selectId}`);
|
|
34352
35467
|
if (input.length === 0) {
|
|
34353
35468
|
return;
|
|
@@ -34370,40 +35485,68 @@ RED.editor = (function() {
|
|
|
34370
35485
|
select.css({
|
|
34371
35486
|
'flex-grow': 1
|
|
34372
35487
|
});
|
|
35488
|
+
|
|
34373
35489
|
updateConfigNodeSelect(property, type, nodeValue, prefix, filter);
|
|
34374
|
-
|
|
34375
|
-
btn.prop( "disabled", !!disabled)
|
|
34376
|
-
btn.toggleClass("disabled", !!disabled)
|
|
34377
|
-
}
|
|
35490
|
+
|
|
34378
35491
|
// create the edit button
|
|
34379
|
-
const
|
|
35492
|
+
const editButton = $('<a id="' + editBtnId + '" class="red-ui-button"><i class="fa fa-pencil"></i></a>')
|
|
34380
35493
|
.css({ "margin-left": "10px" })
|
|
34381
35494
|
.appendTo(outerWrap);
|
|
34382
35495
|
|
|
35496
|
+
RED.popover.tooltip(editButton, RED._('editor.editConfig', { type }));
|
|
35497
|
+
|
|
35498
|
+
// create the add button
|
|
35499
|
+
const addButton = $('<a id="' + addBtnId + '" class="red-ui-button"><i class="fa fa-plus"></i></a>')
|
|
35500
|
+
.css({ "margin-left": "10px" })
|
|
35501
|
+
.appendTo(outerWrap);
|
|
35502
|
+
RED.popover.tooltip(addButton, RED._('editor.addNewConfig', { type }));
|
|
35503
|
+
|
|
35504
|
+
const disableButton = function(button, disabled) {
|
|
35505
|
+
$(button).prop("disabled", !!disabled)
|
|
35506
|
+
$(button).toggleClass("disabled", !!disabled)
|
|
35507
|
+
};
|
|
35508
|
+
|
|
34383
35509
|
// add the click handler
|
|
34384
|
-
|
|
35510
|
+
addButton.on("click", function (e) {
|
|
35511
|
+
if (addButton.prop("disabled")) { return }
|
|
35512
|
+
showEditConfigNodeDialog(property, type, "_ADD_", prefix, node);
|
|
35513
|
+
e.preventDefault();
|
|
35514
|
+
});
|
|
35515
|
+
editButton.on("click", function (e) {
|
|
34385
35516
|
const selectedOpt = select.find(":selected")
|
|
34386
35517
|
if (selectedOpt.data('env')) { return } // don't show the dialog for env vars items (MVP. Future enhancement: lookup the env, if present, show the associated edit dialog)
|
|
34387
|
-
if (
|
|
35518
|
+
if (editButton.prop("disabled")) { return }
|
|
34388
35519
|
showEditConfigNodeDialog(property, type, selectedOpt.val(), prefix, node);
|
|
34389
35520
|
e.preventDefault();
|
|
34390
35521
|
});
|
|
34391
35522
|
|
|
34392
35523
|
// dont permit the user to click the button if the selected option is an env var
|
|
34393
35524
|
select.on("change", function () {
|
|
34394
|
-
const selectedOpt = select.find(":selected")
|
|
35525
|
+
const selectedOpt = select.find(":selected");
|
|
35526
|
+
const optionsLength = select.find("option").length;
|
|
34395
35527
|
if (selectedOpt?.data('env')) {
|
|
34396
|
-
disableButton(true)
|
|
35528
|
+
disableButton(addButton, true);
|
|
35529
|
+
disableButton(editButton, true);
|
|
35530
|
+
// disable the edit button if no options available
|
|
35531
|
+
} else if (optionsLength === 1 && selectedOpt.val() === "_ADD_") {
|
|
35532
|
+
disableButton(addButton, false);
|
|
35533
|
+
disableButton(editButton, true);
|
|
35534
|
+
} else if (selectedOpt.val() === "") {
|
|
35535
|
+
disableButton(addButton, false);
|
|
35536
|
+
disableButton(editButton, true);
|
|
34397
35537
|
} else {
|
|
34398
|
-
disableButton(false)
|
|
35538
|
+
disableButton(addButton, false);
|
|
35539
|
+
disableButton(editButton, false);
|
|
34399
35540
|
}
|
|
34400
35541
|
});
|
|
35542
|
+
|
|
34401
35543
|
var label = "";
|
|
34402
35544
|
var configNode = RED.nodes.node(nodeValue);
|
|
34403
35545
|
|
|
34404
35546
|
if (configNode) {
|
|
34405
35547
|
label = RED.utils.getNodeLabel(configNode, configNode.id);
|
|
34406
35548
|
}
|
|
35549
|
+
|
|
34407
35550
|
input.val(label);
|
|
34408
35551
|
}
|
|
34409
35552
|
|
|
@@ -34897,7 +36040,12 @@ RED.editor = (function() {
|
|
|
34897
36040
|
}
|
|
34898
36041
|
}
|
|
34899
36042
|
|
|
34900
|
-
|
|
36043
|
+
if (!configNodes.length) {
|
|
36044
|
+
select.append('<option value="_ADD_" selected>' + RED._("editor.addNewType", { type: label }) + '</option>');
|
|
36045
|
+
} else {
|
|
36046
|
+
select.append('<option value="">' + RED._("editor.inputs.none") + '</option>');
|
|
36047
|
+
}
|
|
36048
|
+
|
|
34901
36049
|
window.setTimeout(function() { select.trigger("change");},50);
|
|
34902
36050
|
}
|
|
34903
36051
|
}
|
|
@@ -35692,8 +36840,8 @@ RED.editor = (function() {
|
|
|
35692
36840
|
}
|
|
35693
36841
|
|
|
35694
36842
|
if (!isSameObj(old_env, new_env)) {
|
|
35695
|
-
editing_node.env = new_env;
|
|
35696
36843
|
editState.changes.env = editing_node.env;
|
|
36844
|
+
editing_node.env = new_env;
|
|
35697
36845
|
editState.changed = true;
|
|
35698
36846
|
}
|
|
35699
36847
|
|
|
@@ -40936,7 +42084,7 @@ RED.editor.codeEditor.monaco = (function() {
|
|
|
40936
42084
|
_monaco.languages.json.jsonDefaults.setDiagnosticsOptions(diagnosticOptions);
|
|
40937
42085
|
if(modeConfiguration) { _monaco.languages.json.jsonDefaults.setModeConfiguration(modeConfiguration); }
|
|
40938
42086
|
} catch (error) {
|
|
40939
|
-
console.warn("monaco - Error setting up json options",
|
|
42087
|
+
console.warn("monaco - Error setting up json options", error)
|
|
40940
42088
|
}
|
|
40941
42089
|
}
|
|
40942
42090
|
|
|
@@ -40948,7 +42096,7 @@ RED.editor.codeEditor.monaco = (function() {
|
|
|
40948
42096
|
if(htmlDefaults) { _monaco.languages.html.htmlDefaults.setOptions(htmlDefaults); }
|
|
40949
42097
|
if(handlebarDefaults) { _monaco.languages.html.handlebarDefaults.setOptions(handlebarDefaults); }
|
|
40950
42098
|
} catch (error) {
|
|
40951
|
-
console.warn("monaco - Error setting up html options",
|
|
42099
|
+
console.warn("monaco - Error setting up html options", error)
|
|
40952
42100
|
}
|
|
40953
42101
|
}
|
|
40954
42102
|
|
|
@@ -40968,7 +42116,7 @@ RED.editor.codeEditor.monaco = (function() {
|
|
|
40968
42116
|
if(lessDefaults_modeConfiguration) { _monaco.languages.css.cssDefaults.setDiagnosticsOptions(lessDefaults_modeConfiguration); }
|
|
40969
42117
|
if(scssDefaults_modeConfiguration) { _monaco.languages.css.cssDefaults.setDiagnosticsOptions(scssDefaults_modeConfiguration); }
|
|
40970
42118
|
} catch (error) {
|
|
40971
|
-
console.warn("monaco - Error setting up CSS/SCSS/LESS options",
|
|
42119
|
+
console.warn("monaco - Error setting up CSS/SCSS/LESS options", error)
|
|
40972
42120
|
}
|
|
40973
42121
|
}
|
|
40974
42122
|
|
|
@@ -41007,7 +42155,7 @@ RED.editor.codeEditor.monaco = (function() {
|
|
|
41007
42155
|
createMonacoCompletionItem("set (flow context)", 'flow.set("${1:name}", ${1:value});','Set a value in flow context',range),
|
|
41008
42156
|
createMonacoCompletionItem("get (global context)", 'global.get("${1:name}");','Get a value from global context',range),
|
|
41009
42157
|
createMonacoCompletionItem("set (global context)", 'global.set("${1:name}", ${1:value});','Set a value in global context',range),
|
|
41010
|
-
createMonacoCompletionItem("get (env)", 'env.get("${1|NR_NODE_ID,NR_NODE_NAME,NR_NODE_PATH,NR_GROUP_ID,NR_GROUP_NAME,NR_FLOW_ID,NR_FLOW_NAME|}");','Get env variable value',range),
|
|
42158
|
+
createMonacoCompletionItem("get (env)", 'env.get("${1|NR_NODE_ID,NR_NODE_NAME,NR_NODE_PATH,NR_GROUP_ID,NR_GROUP_NAME,NR_FLOW_ID,NR_FLOW_NAME,NR_SUBFLOW_NAME,NR_SUBFLOW_ID,NR_SUBFLOW_PATH|}");','Get env variable value',range),
|
|
41011
42159
|
createMonacoCompletionItem("cloneMessage (RED.util)", 'RED.util.cloneMessage(${1:msg});',
|
|
41012
42160
|
["```typescript",
|
|
41013
42161
|
"RED.util.cloneMessage<T extends registry.NodeMessage>(msg: T): T",
|
|
@@ -42262,6 +43410,7 @@ RED.eventLog = (function() {
|
|
|
42262
43410
|
setTimeout(function() {
|
|
42263
43411
|
oldTray.tray.detach();
|
|
42264
43412
|
showTray(options);
|
|
43413
|
+
RED.events.emit('editor:change')
|
|
42265
43414
|
},250)
|
|
42266
43415
|
} else {
|
|
42267
43416
|
if (stack.length > 0) {
|
|
@@ -42331,6 +43480,7 @@ RED.eventLog = (function() {
|
|
|
42331
43480
|
RED.view.focus();
|
|
42332
43481
|
} else {
|
|
42333
43482
|
stack[stack.length-1].tray.css("z-index", "auto");
|
|
43483
|
+
RED.events.emit('editor:change')
|
|
42334
43484
|
}
|
|
42335
43485
|
},250)
|
|
42336
43486
|
}
|
|
@@ -44784,12 +45934,12 @@ RED.notifications = (function() {
|
|
|
44784
45934
|
if (newType) {
|
|
44785
45935
|
n.className = "red-ui-notification red-ui-notification-"+newType;
|
|
44786
45936
|
}
|
|
44787
|
-
|
|
45937
|
+
newTimeout = newOptions.hasOwnProperty('timeout')?newOptions.timeout:timeout
|
|
44788
45938
|
if (!fixed || newOptions.fixed === false) {
|
|
44789
|
-
newTimeout =
|
|
45939
|
+
newTimeout = newTimeout || 5000
|
|
44790
45940
|
}
|
|
44791
45941
|
if (newOptions.buttons) {
|
|
44792
|
-
var buttonSet = $('<div
|
|
45942
|
+
var buttonSet = $('<div class="ui-dialog-buttonset"></div>').appendTo(nn)
|
|
44793
45943
|
newOptions.buttons.forEach(function(buttonDef) {
|
|
44794
45944
|
var b = $('<button>').text(buttonDef.text).on("click", buttonDef.click).appendTo(buttonSet);
|
|
44795
45945
|
if (buttonDef.id) {
|
|
@@ -44835,6 +45985,15 @@ RED.notifications = (function() {
|
|
|
44835
45985
|
};
|
|
44836
45986
|
})());
|
|
44837
45987
|
n.timeoutid = window.setTimeout(n.close,timeout||5000);
|
|
45988
|
+
} else if (timeout) {
|
|
45989
|
+
$(n).on("click.red-ui-notification-close", (function() {
|
|
45990
|
+
var nn = n;
|
|
45991
|
+
return function() {
|
|
45992
|
+
nn.hideNotification();
|
|
45993
|
+
window.clearTimeout(nn.timeoutid);
|
|
45994
|
+
};
|
|
45995
|
+
})());
|
|
45996
|
+
n.timeoutid = window.setTimeout(n.hideNotification,timeout||5000);
|
|
44838
45997
|
}
|
|
44839
45998
|
currentNotifications.push(n);
|
|
44840
45999
|
if (options.id) {
|
|
@@ -45684,10 +46843,16 @@ RED.search = (function() {
|
|
|
45684
46843
|
onselect: 'core:split-wire-with-link-nodes',
|
|
45685
46844
|
disabled: !canEdit || !hasLinks
|
|
45686
46845
|
},
|
|
45687
|
-
null
|
|
45688
|
-
{ onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
|
|
45689
|
-
{ onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
|
|
46846
|
+
null
|
|
45690
46847
|
)
|
|
46848
|
+
if (RED.settings.theme("menu.menu-item-import-library", true)) {
|
|
46849
|
+
insertOptions.push(
|
|
46850
|
+
{ onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
|
|
46851
|
+
{ onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
|
|
46852
|
+
)
|
|
46853
|
+
}
|
|
46854
|
+
|
|
46855
|
+
|
|
45691
46856
|
if (hasSelection && canEdit) {
|
|
45692
46857
|
const nodeOptions = []
|
|
45693
46858
|
if (!hasMultipleSelection && !isGroup) {
|
|
@@ -45760,8 +46925,14 @@ RED.search = (function() {
|
|
|
45760
46925
|
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
|
|
45761
46926
|
{ onselect: 'core:delete-selection', label: RED._('keyboard.deleteSelected'), disabled: !canEdit || !canDelete },
|
|
45762
46927
|
{ onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
|
|
45763
|
-
|
|
45764
|
-
|
|
46928
|
+
)
|
|
46929
|
+
if (RED.settings.theme("menu.menu-item-export-library", true)) {
|
|
46930
|
+
menuItems.push(
|
|
46931
|
+
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") }
|
|
46932
|
+
)
|
|
46933
|
+
}
|
|
46934
|
+
menuItems.push(
|
|
46935
|
+
{ onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") }
|
|
45765
46936
|
)
|
|
45766
46937
|
}
|
|
45767
46938
|
|
|
@@ -47772,14 +48943,20 @@ RED.subflow = (function() {
|
|
|
47772
48943
|
var nodePropValue = nodeProp;
|
|
47773
48944
|
if (prop.ui && prop.ui.type === "cred") {
|
|
47774
48945
|
nodePropType = "cred";
|
|
48946
|
+
} else if (prop.ui && prop.ui.type === "conf-types") {
|
|
48947
|
+
nodePropType = prop.value.type
|
|
47775
48948
|
} else {
|
|
47776
48949
|
switch(typeof nodeProp) {
|
|
47777
48950
|
case "string": nodePropType = "str"; break;
|
|
47778
48951
|
case "number": nodePropType = "num"; break;
|
|
47779
48952
|
case "boolean": nodePropType = "bool"; nodePropValue = nodeProp?"true":"false"; break;
|
|
47780
48953
|
default:
|
|
47781
|
-
|
|
47782
|
-
|
|
48954
|
+
if (nodeProp) {
|
|
48955
|
+
nodePropType = nodeProp.type;
|
|
48956
|
+
nodePropValue = nodeProp.value;
|
|
48957
|
+
} else {
|
|
48958
|
+
nodePropType = 'str'
|
|
48959
|
+
}
|
|
47783
48960
|
}
|
|
47784
48961
|
}
|
|
47785
48962
|
var item = {
|
|
@@ -47849,7 +49026,7 @@ RED.subflow = (function() {
|
|
|
47849
49026
|
break;
|
|
47850
49027
|
case "conf-types":
|
|
47851
49028
|
item.value = input.val()
|
|
47852
|
-
item.type =
|
|
49029
|
+
item.type = "conf-type"
|
|
47853
49030
|
}
|
|
47854
49031
|
if (ui.type === "cred" || item.type !== data.parent.type || item.value !== data.parent.value) {
|
|
47855
49032
|
env.push(item);
|
|
@@ -51702,7 +52879,7 @@ RED.projects.settings = (function() {
|
|
|
51702
52879
|
var notInstalledCount = 0;
|
|
51703
52880
|
|
|
51704
52881
|
for (var m in modulesInUse) {
|
|
51705
|
-
if (modulesInUse.hasOwnProperty(m)) {
|
|
52882
|
+
if (modulesInUse.hasOwnProperty(m) && !activeProject.dependencies.hasOwnProperty(m)) {
|
|
51706
52883
|
depsList.editableList('addItem',{
|
|
51707
52884
|
id: modulesInUse[m].module,
|
|
51708
52885
|
version: modulesInUse[m].version,
|
|
@@ -51722,8 +52899,8 @@ RED.projects.settings = (function() {
|
|
|
51722
52899
|
|
|
51723
52900
|
if (activeProject.dependencies) {
|
|
51724
52901
|
for (var m in activeProject.dependencies) {
|
|
51725
|
-
if (activeProject.dependencies.hasOwnProperty(m)
|
|
51726
|
-
var installed = !!RED.nodes.registry.getModule(m);
|
|
52902
|
+
if (activeProject.dependencies.hasOwnProperty(m)) {
|
|
52903
|
+
var installed = !!RED.nodes.registry.getModule(m) && activeProject.dependencies[m] === modulesInUse[m].version;
|
|
51727
52904
|
depsList.editableList('addItem',{
|
|
51728
52905
|
id: m,
|
|
51729
52906
|
version: activeProject.dependencies[m], //RED.nodes.registry.getModule(module).version,
|