mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #3405 from Steve-Mcl/continuous-search
Add feature: Continuous search tools (search previous, search next)
This commit is contained in:
commit
a0acc89fcb
@ -149,7 +149,11 @@
|
|||||||
"toggle-navigator": "Toggle navigator",
|
"toggle-navigator": "Toggle navigator",
|
||||||
"zoom-out": "Zoom out",
|
"zoom-out": "Zoom out",
|
||||||
"zoom-reset": "Reset zoom",
|
"zoom-reset": "Reset zoom",
|
||||||
"zoom-in": "Zoom in"
|
"zoom-in": "Zoom in",
|
||||||
|
"search-flows": "Search flows",
|
||||||
|
"search-prev": "Previous",
|
||||||
|
"search-next": "Next",
|
||||||
|
"search-counter": "\"__term__\" __result__ of __count__"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"loggedInAs": "Logged in as __name__",
|
"loggedInAs": "Logged in as __name__",
|
||||||
|
@ -91,6 +91,9 @@
|
|||||||
"alt-a c": "core:align-selection-to-center",
|
"alt-a c": "core:align-selection-to-center",
|
||||||
"alt-a h": "core:distribute-selection-horizontally",
|
"alt-a h": "core:distribute-selection-horizontally",
|
||||||
"alt-a v": "core:distribute-selection-vertically",
|
"alt-a v": "core:distribute-selection-vertically",
|
||||||
|
"shift-f": "core:search-previous",
|
||||||
|
"f": "core:search-next",
|
||||||
"alt-l l": "core:split-wire-with-link-nodes"
|
"alt-l l": "core:split-wire-with-link-nodes"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ RED.search = (function() {
|
|||||||
var searchHistory = [];
|
var searchHistory = [];
|
||||||
var index = {};
|
var index = {};
|
||||||
var currentResults = [];
|
var currentResults = [];
|
||||||
|
var activeResults = [];
|
||||||
|
var currentIndex = 0;
|
||||||
var previousActiveElement;
|
var previousActiveElement;
|
||||||
|
|
||||||
function indexProperty(node,label,property) {
|
function indexProperty(node,label,property) {
|
||||||
@ -329,7 +331,8 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
} else if (!$(children[selected]).hasClass("red-ui-search-historyHeader")) {
|
} else if (!$(children[selected]).hasClass("red-ui-search-historyHeader")) {
|
||||||
if (currentResults.length > 0) {
|
if (currentResults.length > 0) {
|
||||||
reveal(currentResults[Math.max(0,selected)].node);
|
currentIndex = Math.max(0,selected);
|
||||||
|
reveal(currentResults[currentIndex].node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,6 +416,7 @@ RED.search = (function() {
|
|||||||
|
|
||||||
div.on("click", function(evt) {
|
div.on("click", function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
currentIndex = i;
|
||||||
reveal(node);
|
reveal(node);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -428,13 +432,59 @@ RED.search = (function() {
|
|||||||
if (existingIndex > -1) {
|
if (existingIndex > -1) {
|
||||||
searchHistory.splice(existingIndex,1);
|
searchHistory.splice(existingIndex,1);
|
||||||
}
|
}
|
||||||
searchHistory.unshift(searchInput.val());
|
searchHistory.unshift(searchVal);
|
||||||
hide();
|
$("#red-ui-view-searchtools-search").data("term", searchVal);
|
||||||
|
activeResults = Object.assign([], currentResults);
|
||||||
|
hide(null, activeResults.length > 0);
|
||||||
RED.view.reveal(node.id);
|
RED.view.reveal(node.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function revealPrev() {
|
||||||
|
if (disabled) {
|
||||||
|
updateSearchToolbar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!searchResults || !activeResults.length) {
|
||||||
|
show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentIndex > 0) {
|
||||||
|
currentIndex--;
|
||||||
|
} else {
|
||||||
|
currentIndex = activeResults.length - 1;
|
||||||
|
}
|
||||||
|
const n = activeResults[currentIndex];
|
||||||
|
if (n && n.node && n.node.id) {
|
||||||
|
RED.view.reveal(n.node.id);
|
||||||
|
$("#red-ui-view-searchtools-prev").trigger("focus");
|
||||||
|
}
|
||||||
|
updateSearchToolbar();
|
||||||
|
}
|
||||||
|
function revealNext() {
|
||||||
|
if (disabled) {
|
||||||
|
updateSearchToolbar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!searchResults || !activeResults.length) {
|
||||||
|
show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentIndex < activeResults.length - 1) {
|
||||||
|
currentIndex++
|
||||||
|
} else {
|
||||||
|
currentIndex = 0;
|
||||||
|
}
|
||||||
|
const n = activeResults[currentIndex];
|
||||||
|
if (n && n.node && n.node.id) {
|
||||||
|
RED.view.reveal(n.node.id);
|
||||||
|
$("#red-ui-view-searchtools-next").trigger("focus");
|
||||||
|
}
|
||||||
|
updateSearchToolbar();
|
||||||
|
}
|
||||||
|
|
||||||
function show(v) {
|
function show(v) {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
|
updateSearchToolbar();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
@ -461,7 +511,7 @@ RED.search = (function() {
|
|||||||
searchInput.trigger("focus");
|
searchInput.trigger("focus");
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide(el, keepSearchToolbar) {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
visible = false;
|
visible = false;
|
||||||
$("#red-ui-header-shade").hide();
|
$("#red-ui-header-shade").hide();
|
||||||
@ -475,13 +525,37 @@ RED.search = (function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
RED.events.emit("search:close");
|
RED.events.emit("search:close");
|
||||||
if (previousActiveElement) {
|
if (previousActiveElement && (!keepSearchToolbar || !activeResults.length)) {
|
||||||
$(previousActiveElement).trigger("focus");
|
$(previousActiveElement).trigger("focus");
|
||||||
previousActiveElement = null;
|
|
||||||
}
|
}
|
||||||
|
previousActiveElement = null;
|
||||||
|
}
|
||||||
|
if(!keepSearchToolbar) {
|
||||||
|
clearActiveSearch();
|
||||||
|
}
|
||||||
|
updateSearchToolbar();
|
||||||
|
if(keepSearchToolbar && activeResults.length) {
|
||||||
|
$("#red-ui-view-searchtools-next").trigger("focus");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updateSearchToolbar() {
|
||||||
|
if (!disabled && currentIndex >= 0 && activeResults && activeResults.length) {
|
||||||
|
let term = $("#red-ui-view-searchtools-search").data("term") || "";
|
||||||
|
if (term.length > 16) {
|
||||||
|
term = term.substring(0, 12) + "..."
|
||||||
|
}
|
||||||
|
const i18nSearchCounterData = {
|
||||||
|
term: term,
|
||||||
|
result: (currentIndex + 1),
|
||||||
|
count: activeResults.length
|
||||||
|
}
|
||||||
|
$("#red-ui-view-searchtools-counter").text(RED._('actions.search-counter', i18nSearchCounterData));
|
||||||
|
$("#view-search-tools > :not(:first-child)").show(); //show other tools
|
||||||
|
} else {
|
||||||
|
clearActiveSearch();
|
||||||
|
$("#view-search-tools > :not(:first-child)").hide(); //hide all but search button
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearIndex() {
|
function clearIndex() {
|
||||||
index = {};
|
index = {};
|
||||||
}
|
}
|
||||||
@ -503,6 +577,12 @@ RED.search = (function() {
|
|||||||
addItemToIndex(item);
|
addItemToIndex(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearActiveSearch() {
|
||||||
|
activeResults = [];
|
||||||
|
currentIndex = 0;
|
||||||
|
$("#red-ui-view-searchtools-search").data("term", "");
|
||||||
|
}
|
||||||
|
|
||||||
function getSearchOptions() {
|
function getSearchOptions() {
|
||||||
return [
|
return [
|
||||||
{label:RED._("search.options.configNodes"), value:"is:config"},
|
{label:RED._("search.options.configNodes"), value:"is:config"},
|
||||||
@ -513,10 +593,13 @@ RED.search = (function() {
|
|||||||
{label:RED._("search.options.unusedSubflows"), value:"is:subflow is:unused"},
|
{label:RED._("search.options.unusedSubflows"), value:"is:subflow is:unused"},
|
||||||
{label:RED._("search.options.hiddenFlows"), value:"is:hidden"},
|
{label:RED._("search.options.hiddenFlows"), value:"is:hidden"},
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
RED.actions.add("core:search",show);
|
RED.actions.add("core:search",show);
|
||||||
|
RED.actions.add("core:search-previous",revealPrev);
|
||||||
|
RED.actions.add("core:search-next",revealNext);
|
||||||
|
|
||||||
RED.events.on("editor:open",function() { disabled = true; });
|
RED.events.on("editor:open",function() { disabled = true; });
|
||||||
RED.events.on("editor:close",function() { disabled = false; });
|
RED.events.on("editor:close",function() { disabled = false; });
|
||||||
@ -527,11 +610,21 @@ RED.search = (function() {
|
|||||||
|
|
||||||
RED.keyboard.add("red-ui-search","escape",hide);
|
RED.keyboard.add("red-ui-search","escape",hide);
|
||||||
|
|
||||||
|
RED.keyboard.add("view-search-tools","escape",function() {
|
||||||
|
clearActiveSearch();
|
||||||
|
updateSearchToolbar();
|
||||||
|
});
|
||||||
|
|
||||||
$("#red-ui-header-shade").on('mousedown',hide);
|
$("#red-ui-header-shade").on('mousedown',hide);
|
||||||
$("#red-ui-editor-shade").on('mousedown',hide);
|
$("#red-ui-editor-shade").on('mousedown',hide);
|
||||||
$("#red-ui-palette-shade").on('mousedown',hide);
|
$("#red-ui-palette-shade").on('mousedown',hide);
|
||||||
$("#red-ui-sidebar-shade").on('mousedown',hide);
|
$("#red-ui-sidebar-shade").on('mousedown',hide);
|
||||||
|
|
||||||
|
$("#red-ui-view-searchtools-close").on("click", function close() {
|
||||||
|
clearActiveSearch();
|
||||||
|
updateSearchToolbar();
|
||||||
|
});
|
||||||
|
$("#red-ui-view-searchtools-close").trigger("click");
|
||||||
|
|
||||||
RED.events.on("workspace:clear", clearIndex);
|
RED.events.on("workspace:clear", clearIndex);
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ RED.statusBar = (function() {
|
|||||||
function addWidget(options) {
|
function addWidget(options) {
|
||||||
widgets[options.id] = options;
|
widgets[options.id] = options;
|
||||||
var el = $('<span class="red-ui-statusbar-widget"></span>');
|
var el = $('<span class="red-ui-statusbar-widget"></span>');
|
||||||
|
el.prop('id', options.id);
|
||||||
options.element.appendTo(el);
|
options.element.appendTo(el);
|
||||||
if (options.align === 'left') {
|
if (options.align === 'left') {
|
||||||
leftBucket.append(el);
|
leftBucket.append(el);
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
**/
|
**/
|
||||||
RED.sidebar.config = (function() {
|
RED.sidebar.config = (function() {
|
||||||
|
|
||||||
|
let flashingConfigNode;
|
||||||
|
let flashingConfigNodeTimer;
|
||||||
|
|
||||||
var content = document.createElement("div");
|
var content = document.createElement("div");
|
||||||
content.className = "red-ui-sidebar-node-config";
|
content.className = "red-ui-sidebar-node-config";
|
||||||
@ -145,6 +147,7 @@ RED.sidebar.config = (function() {
|
|||||||
var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list);
|
var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list);
|
||||||
var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry);
|
var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry);
|
||||||
entry.data('node',node.id);
|
entry.data('node',node.id);
|
||||||
|
nodeDiv.data('node',node.id);
|
||||||
var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv);
|
var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv);
|
||||||
if (node.d) {
|
if (node.d) {
|
||||||
nodeDiv.addClass("red-ui-palette-node-config-disabled");
|
nodeDiv.addClass("red-ui-palette-node-config-disabled");
|
||||||
@ -350,6 +353,32 @@ RED.sidebar.config = (function() {
|
|||||||
RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes"));
|
RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function flashConfigNode(el) {
|
||||||
|
if(flashingConfigNode && flashingConfigNode.length) {
|
||||||
|
//cancel current flashing node before flashing new node
|
||||||
|
clearInterval(flashingConfigNodeTimer);
|
||||||
|
flashingConfigNodeTimer = null;
|
||||||
|
flashingConfigNode.children("div").removeClass('highlighted');
|
||||||
|
flashingConfigNode = null;
|
||||||
|
}
|
||||||
|
if(!el || !el.children("div").length) { return; }
|
||||||
|
|
||||||
|
flashingConfigNodeTimer = setInterval(function(flashEndTime) {
|
||||||
|
if (flashEndTime >= Date.now()) {
|
||||||
|
const highlighted = el.children("div").hasClass("highlighted");
|
||||||
|
el.children("div").toggleClass('highlighted', !highlighted)
|
||||||
|
} else {
|
||||||
|
clearInterval(flashingConfigNodeTimer);
|
||||||
|
flashingConfigNodeTimer = null;
|
||||||
|
flashingConfigNode = null;
|
||||||
|
el.children("div").removeClass('highlighted');
|
||||||
|
}
|
||||||
|
}, 100, Date.now() + 2200);
|
||||||
|
flashingConfigNode = el;
|
||||||
|
el.children("div").addClass('highlighted');
|
||||||
|
}
|
||||||
|
|
||||||
function show(id) {
|
function show(id) {
|
||||||
if (typeof id === 'boolean') {
|
if (typeof id === 'boolean') {
|
||||||
if (id) {
|
if (id) {
|
||||||
@ -374,19 +403,7 @@ RED.sidebar.config = (function() {
|
|||||||
} else if (y<0) {
|
} else if (y<0) {
|
||||||
scrollWindow.animate({scrollTop: '+='+(y-10)},150);
|
scrollWindow.animate({scrollTop: '+='+(y-10)},150);
|
||||||
}
|
}
|
||||||
var flash = 21;
|
flashConfigNode(node, id);
|
||||||
var flashFunc = function() {
|
|
||||||
if ((flash%2)===0) {
|
|
||||||
node.removeClass('node_highlighted');
|
|
||||||
} else {
|
|
||||||
node.addClass('node_highlighted');
|
|
||||||
}
|
|
||||||
flash--;
|
|
||||||
if (flash >= 0) {
|
|
||||||
setTimeout(flashFunc,100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flashFunc();
|
|
||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
RED.sidebar.show("config");
|
RED.sidebar.show("config");
|
||||||
|
@ -92,6 +92,9 @@ RED.view = (function() {
|
|||||||
var lastClickPosition = [];
|
var lastClickPosition = [];
|
||||||
var selectNodesOptions;
|
var selectNodesOptions;
|
||||||
|
|
||||||
|
let flashingNodeId;
|
||||||
|
let flashingNodeTimer;
|
||||||
|
|
||||||
var clipboard = "";
|
var clipboard = "";
|
||||||
|
|
||||||
// Note: these are the permitted status colour aliases. The actual RGB values
|
// Note: these are the permitted status colour aliases. The actual RGB values
|
||||||
@ -452,6 +455,33 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//add search to status-toolbar
|
||||||
|
RED.statusBar.add({
|
||||||
|
id: "view-search-tools",
|
||||||
|
align: "left",
|
||||||
|
hidden: false,
|
||||||
|
element: $('<span class="button-group">'+
|
||||||
|
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-search"><i class="fa fa-search"></i></button>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span class="button-group search-counter">' +
|
||||||
|
'<span class="red-ui-footer-button" id="red-ui-view-searchtools-counter">? of ?</span>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span class="button-group">' +
|
||||||
|
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-prev"><i class="fa fa-chevron-left"></i></button>' +
|
||||||
|
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-next"><i class="fa fa-chevron-right"></i></button>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span class="button-group">' +
|
||||||
|
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-close"><i class="fa fa-close"></i></button>' +
|
||||||
|
'</span>')
|
||||||
|
})
|
||||||
|
$("#red-ui-view-searchtools-search").on("click", searchFlows);
|
||||||
|
RED.popover.tooltip($("#red-ui-view-searchtools-search"),RED._('actions.search-flows'),'core:search');
|
||||||
|
$("#red-ui-view-searchtools-prev").on("click", searchPrev);
|
||||||
|
RED.popover.tooltip($("#red-ui-view-searchtools-prev"),RED._('actions.search-prev'),'core:search-previous');
|
||||||
|
$("#red-ui-view-searchtools-next").on("click", searchNext);
|
||||||
|
RED.popover.tooltip($("#red-ui-view-searchtools-next"),RED._('actions.search-next'),'core:search-next');
|
||||||
|
RED.popover.tooltip($("#red-ui-view-searchtools-close"),RED._('common.label.close'));
|
||||||
|
|
||||||
// Handle nodes dragged from the palette
|
// Handle nodes dragged from the palette
|
||||||
chart.droppable({
|
chart.droppable({
|
||||||
accept:".red-ui-palette-node",
|
accept:".red-ui-palette-node",
|
||||||
@ -2032,6 +2062,9 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function zoomZero() { zoomView(1); }
|
function zoomZero() { zoomView(1); }
|
||||||
|
function searchFlows() { RED.actions.invoke("core:search", $(this).data("term")); }
|
||||||
|
function searchPrev() { RED.actions.invoke("core:search-previous"); }
|
||||||
|
function searchNext() { RED.actions.invoke("core:search-next"); }
|
||||||
|
|
||||||
|
|
||||||
function zoomView(factor) {
|
function zoomView(factor) {
|
||||||
@ -5805,6 +5838,37 @@ RED.view = (function() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function flashNode(n) {
|
||||||
|
let node = n;
|
||||||
|
if(typeof node === "string") { node = RED.nodes.node(n); }
|
||||||
|
if(!node) { return; }
|
||||||
|
|
||||||
|
const flashingNode = flashingNodeTimer && flashingNodeId && RED.nodes.node(flashingNodeId);
|
||||||
|
if(flashingNode) {
|
||||||
|
//cancel current flashing node before flashing new node
|
||||||
|
clearInterval(flashingNodeTimer);
|
||||||
|
flashingNodeTimer = null;
|
||||||
|
flashingNode.dirty = true;
|
||||||
|
flashingNode.highlighted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
flashingNodeTimer = setInterval(function(flashEndTime) {
|
||||||
|
node.dirty = true;
|
||||||
|
if (flashEndTime >= Date.now()) {
|
||||||
|
node.highlighted = !node.highlighted;
|
||||||
|
} else {
|
||||||
|
clearInterval(flashingNodeTimer);
|
||||||
|
flashingNodeTimer = null;
|
||||||
|
node.highlighted = false;
|
||||||
|
flashingNodeId = null;
|
||||||
|
}
|
||||||
|
RED.view.redraw();
|
||||||
|
}, 100, Date.now() + 2200)
|
||||||
|
flashingNodeId = node.id;
|
||||||
|
node.highlighted = true;
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
state:function(state) {
|
state:function(state) {
|
||||||
@ -5901,7 +5965,7 @@ RED.view = (function() {
|
|||||||
getActiveGroup: function() { return activeGroup },
|
getActiveGroup: function() { return activeGroup },
|
||||||
reveal: function(id,triggerHighlight) {
|
reveal: function(id,triggerHighlight) {
|
||||||
if (RED.nodes.workspace(id) || RED.nodes.subflow(id)) {
|
if (RED.nodes.workspace(id) || RED.nodes.subflow(id)) {
|
||||||
RED.workspaces.show(id);
|
RED.workspaces.show(id, null, null, true);
|
||||||
} else {
|
} else {
|
||||||
var node = RED.nodes.node(id) || RED.nodes.group(id);
|
var node = RED.nodes.node(id) || RED.nodes.group(id);
|
||||||
if (node) {
|
if (node) {
|
||||||
@ -5926,24 +5990,7 @@ RED.view = (function() {
|
|||||||
},200);
|
},200);
|
||||||
}
|
}
|
||||||
if (triggerHighlight !== false) {
|
if (triggerHighlight !== false) {
|
||||||
node.highlighted = true;
|
flashNode(node);
|
||||||
if (!node._flashing) {
|
|
||||||
node._flashing = true;
|
|
||||||
var flash = 22;
|
|
||||||
var flashFunc = function() {
|
|
||||||
flash--;
|
|
||||||
node.dirty = true;
|
|
||||||
if (flash >= 0) {
|
|
||||||
node.highlighted = !node.highlighted;
|
|
||||||
setTimeout(flashFunc,100);
|
|
||||||
} else {
|
|
||||||
node.highlighted = false;
|
|
||||||
delete node._flashing;
|
|
||||||
}
|
|
||||||
RED.view.redraw();
|
|
||||||
}
|
|
||||||
flashFunc();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (node._def.category === 'config') {
|
} else if (node._def.category === 'config') {
|
||||||
RED.sidebar.config.show(id);
|
RED.sidebar.config.show(id);
|
||||||
|
@ -24,6 +24,9 @@ RED.workspaces = (function() {
|
|||||||
var hideStack = [];
|
var hideStack = [];
|
||||||
var viewStackPos = 0;
|
var viewStackPos = 0;
|
||||||
|
|
||||||
|
let flashingTab;
|
||||||
|
let flashingTabTimer;
|
||||||
|
|
||||||
function addToViewStack(id) {
|
function addToViewStack(id) {
|
||||||
if (viewStackPos !== viewStack.length) {
|
if (viewStackPos !== viewStack.length) {
|
||||||
viewStack.splice(viewStackPos);
|
viewStack.splice(viewStackPos);
|
||||||
@ -531,6 +534,31 @@ RED.workspaces = (function() {
|
|||||||
workspace_tabs.order(order);
|
workspace_tabs.order(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function flashTab(tabId) {
|
||||||
|
if(flashingTab && flashingTab.length) {
|
||||||
|
//cancel current flashing node before flashing new node
|
||||||
|
clearInterval(flashingTabTimer);
|
||||||
|
flashingTabTimer = null;
|
||||||
|
flashingTab.removeClass('highlighted');
|
||||||
|
flashingTab = null;
|
||||||
|
}
|
||||||
|
let tab = $("#red-ui-tab-" + tabId);
|
||||||
|
if(!tab || !tab.length) { return; }
|
||||||
|
|
||||||
|
flashingTabTimer = setInterval(function(flashEndTime) {
|
||||||
|
if (flashEndTime >= Date.now()) {
|
||||||
|
const highlighted = tab.hasClass("highlighted");
|
||||||
|
tab.toggleClass('highlighted', !highlighted)
|
||||||
|
} else {
|
||||||
|
clearInterval(flashingTabTimer);
|
||||||
|
flashingTabTimer = null;
|
||||||
|
flashingTab = null;
|
||||||
|
tab.removeClass('highlighted');
|
||||||
|
}
|
||||||
|
}, 100, Date.now() + 2200);
|
||||||
|
flashingTab = tab;
|
||||||
|
tab.addClass('highlighted');
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
add: addWorkspace,
|
add: addWorkspace,
|
||||||
@ -563,7 +591,7 @@ RED.workspaces = (function() {
|
|||||||
isHidden: function(id) {
|
isHidden: function(id) {
|
||||||
return hideStack.includes(id)
|
return hideStack.includes(id)
|
||||||
},
|
},
|
||||||
show: function(id,skipStack,unhideOnly) {
|
show: function(id,skipStack,unhideOnly,flash) {
|
||||||
if (!workspace_tabs.contains(id)) {
|
if (!workspace_tabs.contains(id)) {
|
||||||
var sf = RED.nodes.subflow(id);
|
var sf = RED.nodes.subflow(id);
|
||||||
if (sf) {
|
if (sf) {
|
||||||
@ -585,6 +613,9 @@ RED.workspaces = (function() {
|
|||||||
}
|
}
|
||||||
workspace_tabs.activateTab(id);
|
workspace_tabs.activateTab(id);
|
||||||
}
|
}
|
||||||
|
if(flash) {
|
||||||
|
flashTab(id.replace(".","-"))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
RED.nodes.eachWorkspace(function(ws) {
|
RED.nodes.eachWorkspace(function(ws) {
|
||||||
|
@ -42,6 +42,10 @@ ul.red-ui-sidebar-node-config-list {
|
|||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: 0 0 0 2px $node-selected-color;
|
box-shadow: 0 0 0 2px $node-selected-color;
|
||||||
}
|
}
|
||||||
|
&.highlighted {
|
||||||
|
border-color: transparent;
|
||||||
|
outline: dashed $node-selected-color 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.red-ui-palette-label {
|
.red-ui-palette-label {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
|
@ -85,6 +85,10 @@
|
|||||||
&:not(.active) a:hover+a.red-ui-tab-close {
|
&:not(.active) a:hover+a.red-ui-tab-close {
|
||||||
background: $tab-background-hover;
|
background: $tab-background-hover;
|
||||||
}
|
}
|
||||||
|
&.highlighted {
|
||||||
|
box-shadow: 0px 0px 4px 2px $node-selected-color;
|
||||||
|
border: dashed 1px $node-selected-color;
|
||||||
|
}
|
||||||
&.active {
|
&.active {
|
||||||
background: $tab-background-active;
|
background: $tab-background-active;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -135,6 +135,13 @@
|
|||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-counter {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: smaller;
|
||||||
|
font-weight: 600;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.red-ui-footer-button,
|
a.red-ui-footer-button,
|
||||||
|
Loading…
Reference in New Issue
Block a user