mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge pull request #5021 from node-red/5008-remember-context-tree-state
Remember context sidebar tree state when refreshing
This commit is contained in:
		@@ -18,8 +18,6 @@ RED.sidebar.context = (function() {
 | 
			
		||||
    var content;
 | 
			
		||||
    var sections;
 | 
			
		||||
 | 
			
		||||
    var localCache = {};
 | 
			
		||||
 | 
			
		||||
    var flowAutoRefresh;
 | 
			
		||||
    var nodeAutoRefresh;
 | 
			
		||||
    var nodeSection;
 | 
			
		||||
@@ -27,6 +25,8 @@ RED.sidebar.context = (function() {
 | 
			
		||||
    var flowSection;
 | 
			
		||||
    var globalSection;
 | 
			
		||||
 | 
			
		||||
    const expandedPaths = {}
 | 
			
		||||
 | 
			
		||||
    var currentNode;
 | 
			
		||||
    var currentFlow;
 | 
			
		||||
 | 
			
		||||
@@ -212,14 +212,41 @@ RED.sidebar.context = (function() {
 | 
			
		||||
            var l = keys.length;
 | 
			
		||||
            for (var i = 0; i < l; i++) {
 | 
			
		||||
                sortedData[keys[i]].forEach(function(v) {
 | 
			
		||||
                    var k = keys[i];
 | 
			
		||||
                    var l2 = sortedData[k].length;
 | 
			
		||||
                    var propRow = $('<tr class="red-ui-help-info-row"><td class="red-ui-sidebar-context-property"></td><td></td></tr>').appendTo(container);
 | 
			
		||||
                    var obj = $(propRow.children()[0]);
 | 
			
		||||
                    const k = keys[i];
 | 
			
		||||
                    let payload = v.msg;
 | 
			
		||||
                    let format = v.format;
 | 
			
		||||
                    const tools = $('<span class="button-group"></span>');
 | 
			
		||||
                    expandedPaths[id + "." + k] = expandedPaths[id + "." + k] || new Set()
 | 
			
		||||
                    const objectElementOptions = {
 | 
			
		||||
                        typeHint: format,
 | 
			
		||||
                        sourceId: id + "." + k,
 | 
			
		||||
                        tools,
 | 
			
		||||
                        path: k,
 | 
			
		||||
                        rootPath: k,
 | 
			
		||||
                        exposeApi: true,
 | 
			
		||||
                        ontoggle: function(path,state) {
 | 
			
		||||
                            path = path.substring(k.length+1)
 | 
			
		||||
                            if (state) {
 | 
			
		||||
                                expandedPaths[id+"."+k].add(path)
 | 
			
		||||
                            } else {
 | 
			
		||||
                                // if 'a' has been collapsed, we want to remove 'a.b' and 'a[0]...' from the set
 | 
			
		||||
                                // of collapsed paths
 | 
			
		||||
                                for (let expandedPath of expandedPaths[id+"."+k]) {
 | 
			
		||||
                                    if (expandedPath.startsWith(path+".") || expandedPath.startsWith(path+"[")) {
 | 
			
		||||
                                        expandedPaths[id+"."+k].delete(expandedPath)
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                expandedPaths[id+"."+k].delete(path)
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        expandPaths: [ ...expandedPaths[id+"."+k] ].sort(),
 | 
			
		||||
                        expandLeafNodes: true
 | 
			
		||||
                    }
 | 
			
		||||
                    const propRow = $('<tr class="red-ui-help-info-row"><td class="red-ui-sidebar-context-property"></td><td></td></tr>').appendTo(container);
 | 
			
		||||
                    const obj = $(propRow.children()[0]);
 | 
			
		||||
                    obj.text(k);
 | 
			
		||||
                    var tools = $('<span class="button-group"></span>');
 | 
			
		||||
                    const urlSafeK = encodeURIComponent(k)
 | 
			
		||||
                    var refreshItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>').appendTo(tools).on("click", function(e) {
 | 
			
		||||
                    const refreshItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>').appendTo(tools).on("click", function(e) {
 | 
			
		||||
                        e.preventDefault();
 | 
			
		||||
                        e.stopPropagation();
 | 
			
		||||
                        $.getJSON(baseUrl+"/"+urlSafeK+"?store="+v.store, function(data) {
 | 
			
		||||
@@ -229,16 +256,14 @@ RED.sidebar.context = (function() {
 | 
			
		||||
                                tools.detach();
 | 
			
		||||
                                $(propRow.children()[1]).empty();
 | 
			
		||||
                                RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), {
 | 
			
		||||
                                    ...objectElementOptions,
 | 
			
		||||
                                    typeHint: data.format,
 | 
			
		||||
                                    sourceId: id+"."+k,
 | 
			
		||||
                                    tools: tools,
 | 
			
		||||
                                    path: k
 | 
			
		||||
                                }).appendTo(propRow.children()[1]);
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                    });
 | 
			
		||||
                    RED.popover.tooltip(refreshItem,RED._("sidebar.context.refrsh"));
 | 
			
		||||
                    var deleteItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>').appendTo(tools).on("click", function(e) {
 | 
			
		||||
                    const deleteItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>').appendTo(tools).on("click", function(e) {
 | 
			
		||||
                        e.preventDefault();
 | 
			
		||||
                        e.stopPropagation();
 | 
			
		||||
                        var popover = RED.popover.create({
 | 
			
		||||
@@ -246,7 +271,7 @@ RED.sidebar.context = (function() {
 | 
			
		||||
                            target: propRow,
 | 
			
		||||
                            direction: "left",
 | 
			
		||||
                            content: function() {
 | 
			
		||||
                                var content = $('<div>');
 | 
			
		||||
                                const content = $('<div>');
 | 
			
		||||
                                $('<p data-i18n="sidebar.context.deleteConfirm"></p>').appendTo(content);
 | 
			
		||||
                                var row = $('<p>').appendTo(content);
 | 
			
		||||
                                var bg = $('<span class="button-group"></span>').appendTo(row);
 | 
			
		||||
@@ -269,16 +294,15 @@ RED.sidebar.context = (function() {
 | 
			
		||||
                                                if (container.children().length === 0) {
 | 
			
		||||
                                                    $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.empty"></td></tr>').appendTo(container).i18n();
 | 
			
		||||
                                                }
 | 
			
		||||
                                                delete expandedPaths[id + "." + k]
 | 
			
		||||
                                            } else {
 | 
			
		||||
                                                payload = data.msg;
 | 
			
		||||
                                                format = data.format;
 | 
			
		||||
                                                tools.detach();
 | 
			
		||||
                                                $(propRow.children()[1]).empty();
 | 
			
		||||
                                                RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), {
 | 
			
		||||
                                                    typeHint: data.format,
 | 
			
		||||
                                                    sourceId: id+"."+k,
 | 
			
		||||
                                                    tools: tools,
 | 
			
		||||
                                                    path: k
 | 
			
		||||
                                                    ...objectElementOptions,
 | 
			
		||||
                                                    typeHint: data.format
 | 
			
		||||
                                                }).appendTo(propRow.children()[1]);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        });
 | 
			
		||||
@@ -293,14 +317,7 @@ RED.sidebar.context = (function() {
 | 
			
		||||
 | 
			
		||||
                    });
 | 
			
		||||
                    RED.popover.tooltip(deleteItem,RED._("sidebar.context.delete"));
 | 
			
		||||
                    var payload = v.msg;
 | 
			
		||||
                    var format = v.format;
 | 
			
		||||
                    RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), {
 | 
			
		||||
                        typeHint: v.format,
 | 
			
		||||
                        sourceId: id+"."+k,
 | 
			
		||||
                        tools: tools,
 | 
			
		||||
                        path: k
 | 
			
		||||
                    }).appendTo(propRow.children()[1]);
 | 
			
		||||
                    RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), objectElementOptions).appendTo(propRow.children()[1]);
 | 
			
		||||
                    if (contextStores.length > 1) {
 | 
			
		||||
                        $("<span>",{class:"red-ui-sidebar-context-property-storename"}).text(v.store).appendTo($(propRow.children()[0]))
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -230,7 +230,7 @@ RED.utils = (function() {
 | 
			
		||||
    var pinnedPaths = {};
 | 
			
		||||
    var formattedPaths = {};
 | 
			
		||||
 | 
			
		||||
    function addMessageControls(obj,sourceId,key,msg,rootPath,strippedKey,extraTools) {
 | 
			
		||||
    function addMessageControls(obj,sourceId,key,msg,rootPath,strippedKey,extraTools,enablePinning) {
 | 
			
		||||
        if (!pinnedPaths.hasOwnProperty(sourceId)) {
 | 
			
		||||
            pinnedPaths[sourceId] = {}
 | 
			
		||||
        }
 | 
			
		||||
@@ -250,7 +250,7 @@ RED.utils = (function() {
 | 
			
		||||
            RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue");
 | 
			
		||||
        })
 | 
			
		||||
        RED.popover.tooltip(copyPayload,RED._("node-red:debug.sidebar.copyPayload"));
 | 
			
		||||
        if (strippedKey !== undefined && strippedKey !== '') {
 | 
			
		||||
        if (enablePinning && strippedKey !== undefined && strippedKey !== '') {
 | 
			
		||||
            var isPinned = pinnedPaths[sourceId].hasOwnProperty(strippedKey);
 | 
			
		||||
 | 
			
		||||
            var pinPath = $('<button class="red-ui-button red-ui-button-small red-ui-debug-msg-tools-pin"><i class="fa fa-map-pin"></i></button>').appendTo(tools).on("click", function(e) {
 | 
			
		||||
@@ -281,13 +281,16 @@ RED.utils = (function() {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    function checkExpanded(strippedKey,expandPaths,minRange,maxRange) {
 | 
			
		||||
    function checkExpanded(strippedKey, expandPaths, { minRange, maxRange, expandLeafNodes }) {
 | 
			
		||||
        if (expandPaths && expandPaths.length > 0) {
 | 
			
		||||
            if (strippedKey === '' && minRange === undefined) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            for (var i=0;i<expandPaths.length;i++) {
 | 
			
		||||
                var p = expandPaths[i];
 | 
			
		||||
                if (expandLeafNodes && p === strippedKey) {
 | 
			
		||||
                    return true
 | 
			
		||||
                }
 | 
			
		||||
                if (p.indexOf(strippedKey) === 0 && (p[strippedKey.length] === "." ||  p[strippedKey.length] === "[") ) {
 | 
			
		||||
 | 
			
		||||
                    if (minRange !== undefined && p[strippedKey.length] === "[") {
 | 
			
		||||
@@ -394,6 +397,8 @@ RED.utils = (function() {
 | 
			
		||||
        var sourceId = options.sourceId;
 | 
			
		||||
        var rootPath = options.rootPath;
 | 
			
		||||
        var expandPaths = options.expandPaths;
 | 
			
		||||
        const enablePinning = options.enablePinning
 | 
			
		||||
        const expandLeafNodes = options.expandLeafNodes;
 | 
			
		||||
        var ontoggle = options.ontoggle;
 | 
			
		||||
        var exposeApi = options.exposeApi;
 | 
			
		||||
        var tools = options.tools;
 | 
			
		||||
@@ -416,11 +421,11 @@ RED.utils = (function() {
 | 
			
		||||
        }
 | 
			
		||||
        header = $('<span class="red-ui-debug-msg-row"></span>').appendTo(element);
 | 
			
		||||
        if (sourceId) {
 | 
			
		||||
            addMessageControls(header,sourceId,path,obj,rootPath,strippedKey,tools);
 | 
			
		||||
            addMessageControls(header,sourceId,path,obj,rootPath,strippedKey,tools, enablePinning);
 | 
			
		||||
        }
 | 
			
		||||
        if (!key) {
 | 
			
		||||
            element.addClass("red-ui-debug-msg-top-level");
 | 
			
		||||
            if (sourceId) {
 | 
			
		||||
            if (sourceId && !expandPaths) {
 | 
			
		||||
                var pinned = pinnedPaths[sourceId];
 | 
			
		||||
                expandPaths = [];
 | 
			
		||||
                if (pinned) {
 | 
			
		||||
@@ -476,7 +481,7 @@ RED.utils = (function() {
 | 
			
		||||
                    $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-type-header"></span>').text(typeHint||'string').appendTo(header);
 | 
			
		||||
                    var row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(element);
 | 
			
		||||
                    $('<pre class="red-ui-debug-msg-type-string"></pre>').text(obj).appendTo(row);
 | 
			
		||||
                },function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey,expandPaths));
 | 
			
		||||
                },function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey, expandPaths, { expandLeafNodes }));
 | 
			
		||||
            }
 | 
			
		||||
            e = $('<span class="red-ui-debug-msg-type-string red-ui-debug-msg-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj);
 | 
			
		||||
            if (/^#[0-9a-f]{6}$/i.test(obj)) {
 | 
			
		||||
@@ -592,14 +597,16 @@ RED.utils = (function() {
 | 
			
		||||
                                    typeHint: type==='buffer'?'hex':false,
 | 
			
		||||
                                    hideKey: false,
 | 
			
		||||
                                    path: path+"["+i+"]",
 | 
			
		||||
                                    sourceId: sourceId,
 | 
			
		||||
                                    rootPath: rootPath,
 | 
			
		||||
                                    expandPaths: expandPaths,
 | 
			
		||||
                                    ontoggle: ontoggle,
 | 
			
		||||
                                    exposeApi: exposeApi,
 | 
			
		||||
                                    sourceId,
 | 
			
		||||
                                    rootPath,
 | 
			
		||||
                                    expandPaths,
 | 
			
		||||
                                    expandLeafNodes,
 | 
			
		||||
                                    ontoggle,
 | 
			
		||||
                                    exposeApi,
 | 
			
		||||
                                    // tools: tools // Do not pass tools down as we
 | 
			
		||||
                                                    // keep them attached to the top-level header
 | 
			
		||||
                                    nodeSelector: options.nodeSelector,
 | 
			
		||||
                                    enablePinning
 | 
			
		||||
                                }
 | 
			
		||||
                            ).appendTo(row);
 | 
			
		||||
                        }
 | 
			
		||||
@@ -623,21 +630,23 @@ RED.utils = (function() {
 | 
			
		||||
                                                typeHint: type==='buffer'?'hex':false,
 | 
			
		||||
                                                hideKey: false,
 | 
			
		||||
                                                path: path+"["+i+"]",
 | 
			
		||||
                                                sourceId: sourceId,
 | 
			
		||||
                                                rootPath: rootPath,
 | 
			
		||||
                                                expandPaths: expandPaths,
 | 
			
		||||
                                                ontoggle: ontoggle,
 | 
			
		||||
                                                exposeApi: exposeApi,
 | 
			
		||||
                                                sourceId,
 | 
			
		||||
                                                rootPath,
 | 
			
		||||
                                                expandPaths,
 | 
			
		||||
                                                expandLeafNodes,
 | 
			
		||||
                                                ontoggle,
 | 
			
		||||
                                                exposeApi,
 | 
			
		||||
                                                // tools: tools // Do not pass tools down as we
 | 
			
		||||
                                                                // keep them attached to the top-level header
 | 
			
		||||
                                                nodeSelector: options.nodeSelector,
 | 
			
		||||
                                                enablePinning
 | 
			
		||||
                                            }
 | 
			
		||||
                                        ).appendTo(row);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            })(),
 | 
			
		||||
                            (function() { var path = path+"["+i+"]"; return function(state) {if (ontoggle) { ontoggle(path,state);}}})(),
 | 
			
		||||
                            checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9))));
 | 
			
		||||
                            checkExpanded(strippedKey,expandPaths,{ minRange, maxRange: Math.min(fullLength-1,(minRange+9)), expandLeafNodes}));
 | 
			
		||||
                            $('<span class="red-ui-debug-msg-object-key"></span>').html("["+minRange+" … "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (fullLength < originalLength) {
 | 
			
		||||
@@ -646,7 +655,7 @@ RED.utils = (function() {
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                function(state) {if (ontoggle) { ontoggle(path,state);}},
 | 
			
		||||
                checkExpanded(strippedKey,expandPaths));
 | 
			
		||||
                checkExpanded(strippedKey, expandPaths, { expandLeafNodes }));
 | 
			
		||||
            }
 | 
			
		||||
        } else if (typeof obj === 'object') {
 | 
			
		||||
            element.addClass('collapsed');
 | 
			
		||||
@@ -680,14 +689,16 @@ RED.utils = (function() {
 | 
			
		||||
                                typeHint: false,
 | 
			
		||||
                                hideKey: false,
 | 
			
		||||
                                path: newPath,
 | 
			
		||||
                                sourceId: sourceId,
 | 
			
		||||
                                rootPath: rootPath,
 | 
			
		||||
                                expandPaths: expandPaths,
 | 
			
		||||
                                ontoggle: ontoggle,
 | 
			
		||||
                                exposeApi: exposeApi,
 | 
			
		||||
                                sourceId,
 | 
			
		||||
                                rootPath,
 | 
			
		||||
                                expandPaths,
 | 
			
		||||
                                expandLeafNodes,
 | 
			
		||||
                                ontoggle,
 | 
			
		||||
                                exposeApi,
 | 
			
		||||
                                // tools: tools // Do not pass tools down as we
 | 
			
		||||
                                                // keep them attached to the top-level header
 | 
			
		||||
                                nodeSelector: options.nodeSelector,
 | 
			
		||||
                                enablePinning
 | 
			
		||||
                            }
 | 
			
		||||
                        ).appendTo(row);
 | 
			
		||||
                    }
 | 
			
		||||
@@ -696,7 +707,7 @@ RED.utils = (function() {
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                function(state) {if (ontoggle) { ontoggle(path,state);}},
 | 
			
		||||
                checkExpanded(strippedKey,expandPaths));
 | 
			
		||||
                checkExpanded(strippedKey, expandPaths, { expandLeafNodes }));
 | 
			
		||||
            }
 | 
			
		||||
            if (key) {
 | 
			
		||||
                $('<span class="red-ui-debug-msg-type-meta"></span>').text(type).appendTo(entryObj);
 | 
			
		||||
 
 | 
			
		||||
@@ -511,9 +511,10 @@ RED.debug = (function() {
 | 
			
		||||
            typeHint: format,
 | 
			
		||||
            hideKey: false,
 | 
			
		||||
            path: path,
 | 
			
		||||
            sourceId: sourceNode&&sourceNode.id,
 | 
			
		||||
            sourceId: sourceNode && sourceNode.id,
 | 
			
		||||
            rootPath: path,
 | 
			
		||||
            nodeSelector: config.messageSourceClick,
 | 
			
		||||
            enablePinning: true
 | 
			
		||||
        });
 | 
			
		||||
        // Do this in a separate step so the element functions aren't stripped
 | 
			
		||||
        debugMessage.appendTo(el);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user