mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Add initial tour-guide feature
This commit is contained in:
		
							
								
								
									
										15
									
								
								Gruntfile.js
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Gruntfile.js
									
									
									
									
									
								
							| @@ -199,7 +199,8 @@ module.exports = function(grunt) { | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js" | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tour/*.js" | ||||
|                 ], | ||||
|                 dest: "packages/node_modules/@node-red/editor-client/public/red/red.js" | ||||
|             }, | ||||
| @@ -326,6 +327,12 @@ module.exports = function(grunt) { | ||||
|                 ], | ||||
|                 tasks: ['jsonlint:keymaps','copy:build'] | ||||
|             }, | ||||
|             tours: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/tours/**/*.js' | ||||
|                 ], | ||||
|                 tasks: ['copy:build'] | ||||
|             }, | ||||
|             misc: { | ||||
|                 files: [ | ||||
|                     'CHANGELOG.md' | ||||
| @@ -423,6 +430,12 @@ module.exports = function(grunt) { | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/vendor/ace/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/tours', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/tours/' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|   | ||||
							
								
								
									
										360
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/tour/tourGuide.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/tour/tourGuide.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,360 @@ | ||||
| RED.tourGuide = (function() { | ||||
|     var activeListeners = []; | ||||
|     var shade; | ||||
|     var focus; | ||||
|     var popover; | ||||
|     var stepContent; | ||||
|     var targetElement; | ||||
|     var fullscreen; | ||||
|  | ||||
|     var tourCache = {}; | ||||
|  | ||||
|     function run(tourPath, done) { | ||||
|         done = done || function(err) { | ||||
|             if (err) { | ||||
|                 console.error(err); | ||||
|             } | ||||
|         }; | ||||
|         if (tourCache[tourPath]) { | ||||
|             runTour(tourCache[tourPath],done); | ||||
|         } else { | ||||
|             import(tourPath).then(function(module) { | ||||
|                 tourCache[tourPath] = module.default; | ||||
|                 runTour(tourCache[tourPath],done); | ||||
|             }).catch(function(err) { | ||||
|                 console.warn("Error loading tour:",err); | ||||
|                 done(err); | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function repositionFocus() { | ||||
|         if (targetElement) { | ||||
|             var pos = targetElement[0].getBoundingClientRect(); | ||||
|             var dimension = Math.max(50, Math.max(pos.width,pos.height)*1.5); | ||||
|             if (!fullscreen) { | ||||
|                 focus.css({ | ||||
|                     left: (pos.left+pos.width/2)+"px", | ||||
|                     top: (pos.top+pos.height/2)+"px", | ||||
|                     width: (2*dimension)+"px", | ||||
|                     height: (2*dimension)+"px" | ||||
|                 }) | ||||
|                 focus[0].offsetHeight; // Flush CSS changes | ||||
|                 focus.addClass("transition"); | ||||
|                 focus.css({ | ||||
|                     width: dimension+"px", | ||||
|                     height: dimension+"px" | ||||
|                 }) | ||||
|             } else { | ||||
|                 focus.css({ | ||||
|                     left: ($(window).width()/2)+"px", | ||||
|                     top: ($(window).height()/2)+"px", | ||||
|                     width: "0px", | ||||
|                     height: "0px" | ||||
|                 }) | ||||
|             } | ||||
|             if (popover) { | ||||
|                 popover.move({ | ||||
|                     target: targetElement, | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     function runTour(tour, done) { | ||||
|  | ||||
|         shade = $('<div class="red-ui-tourGuide-shade"></div>').appendTo(document.body); | ||||
|         focus = $('<div class="red-ui-tourGuide-shade-focus"></div>').appendTo(shade); | ||||
|  | ||||
|         // var resizeTimer; | ||||
|         // | ||||
|         $(window).on("resize.red-ui-tourGuide", function() { | ||||
|             repositionFocus(); | ||||
|         }) | ||||
|  | ||||
|  | ||||
|  | ||||
|         var i = 0; | ||||
|         var state = { | ||||
|             index: 0, | ||||
|             count: tour.steps.length | ||||
|         }; | ||||
|  | ||||
|         function endTour(err) { | ||||
|             $(window).off("resize.red-ui-tourGuide"); | ||||
|             if (popover) { | ||||
|                 popover.close(); | ||||
|             } | ||||
|             stepContent = null; | ||||
|             popover = null; | ||||
|             shade.remove(); | ||||
|             shade = null; | ||||
|             done(err); | ||||
|         } | ||||
|         function runStep(carryOn) { | ||||
|             if (carryOn === false) { | ||||
|                 endTour(false); | ||||
|                 return; | ||||
|             } | ||||
|             if (i === tour.steps.length) { | ||||
|                 endTour(); | ||||
|                 return | ||||
|             } | ||||
|             state.index = i; | ||||
|             // console.log("TOUR STEP",i+1,"OF",tour.steps.length) | ||||
|             try { | ||||
|                 runTourStep(tour.steps[i++], state, runStep) | ||||
|             } catch(err) { | ||||
|                 endTour(err); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         runStep(); | ||||
|     } | ||||
|  | ||||
|     function clearListeners() { | ||||
|         activeListeners.forEach(function(listener) { | ||||
|             if (listener.type === "dom-event") { | ||||
|                 listener.target[0].removeEventListener(listener.event,listener.listener,listener.opts); | ||||
|             } else if (listener.type === "nr-event") { | ||||
|                 RED.events.off(listener.event, listener.listener) | ||||
|             } | ||||
|         }) | ||||
|         activeListeners = []; | ||||
|     } | ||||
|  | ||||
|     function prepareStep(step, state, done) { | ||||
|         if (step.prepare) { | ||||
|             if (step.prepare.length === 0) { | ||||
|                 step.prepare.call(state); | ||||
|             } else { | ||||
|                 step.prepare.call(state, done) | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         done(); | ||||
|     } | ||||
|     function completeStep(step, state, done) { | ||||
|         function finish() { | ||||
|             clearListeners(); | ||||
|             setTimeout(function() { | ||||
|                 done(); | ||||
|             },0) | ||||
|         } | ||||
|         if (step.complete) { | ||||
|             if (step.complete.length === 0) { | ||||
|                 step.complete.call(state); | ||||
|             } else { | ||||
|                 step.complete.call(state, finish) | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         finish(); | ||||
|  | ||||
|     } | ||||
|     function runTourStep(step, state, done) { | ||||
|         shade.fadeIn(); | ||||
|         prepareStep(step, state, function() { | ||||
|             var zIndex; | ||||
|             var direction = step.direction || "bottom"; | ||||
|             fullscreen = false; | ||||
|  | ||||
|             if (typeof step.element === "string") { | ||||
|                 targetElement = $(step.element) | ||||
|             } else if (typeof step.element === "function") { | ||||
|                 targetElement = step.element.call(state); | ||||
|             } else if (!step.element) { | ||||
|                 targetElement = $(".red-ui-editor") | ||||
|                 fullscreen = true; | ||||
|                 direction = "inset"; | ||||
|             } else { | ||||
|                 targetElement = step.element; | ||||
|             } | ||||
|  | ||||
|             if (targetElement.length === 0) { | ||||
|                 targetElement = null; | ||||
|                 shade.hide(); | ||||
|                 throw new Error("Element not found") | ||||
|             } | ||||
|  | ||||
|             zIndex = targetElement.css("z-index"); | ||||
|             if (!fullscreen) { | ||||
|                 targetElement.css("z-index",2002); | ||||
|             } | ||||
|             repositionFocus(); | ||||
|             focus.toggleClass("disableInteraction", step.interactive === false) | ||||
|  | ||||
|             if (!stepContent) { | ||||
|                 stepContent = $('<div style="position:relative"></div>'); | ||||
|             } else { | ||||
|                 stepContent.empty(); | ||||
|             } | ||||
|             $('<button type="button" class="red-ui-button red-ui-button-small" style="float: right; margin-top: -4px; margin-right: -4px;"><i class="fa fa-times"></i></button>').appendTo(stepContent).click(function(evt) { | ||||
|                 evt.preventDefault(); | ||||
|                 completeStep(step, state, function() { | ||||
|                     done(false); | ||||
|                 }); | ||||
|             }) | ||||
|  | ||||
|             var stepDescription = $('<div class="red-ui-tourGuide-popover-description"></div>').appendTo(stepContent); | ||||
|             if (step.titleIcon) { | ||||
|                 $('<h2><i class="'+step.titleIcon+'"></i></h2>').appendTo(stepDescription); | ||||
|             } | ||||
|             if (step.title) { | ||||
|                 $('<h2>').text(step.title).appendTo(stepDescription); | ||||
|             } | ||||
|             $('<div>').css("text-align","left").html(step.description).appendTo(stepDescription); | ||||
|  | ||||
|             var stepToolbar = $('<div>',{class:"red-ui-tourGuide-toolbar"}).appendTo(stepContent); | ||||
|  | ||||
|             // var breadcrumbs = $('<div>',{class:"red-ui-tourGuide-breadcrumbs"}).appendTo(stepToolbar); | ||||
|             // var bcStart = Math.max(0,state.index - 3); | ||||
|             // var bcEnd = Math.min(state.count, bcStart + 7); | ||||
|             // if (bcEnd === state.count) { | ||||
|             //     bcStart = Math.max(0,bcEnd - 7); | ||||
|             // } | ||||
|             // for (var i = bcStart; i < bcEnd; i++) { | ||||
|             //     var bullet = $('<i class="fa"></i>').addClass(i===state.index ? "fa-circle":"fa-circle-o").appendTo(breadcrumbs); | ||||
|             //     if (i === bcStart) { | ||||
|             //         if (i > 1) { | ||||
|             //             bullet.css("font-size", "3px"); | ||||
|             //         } else if (i === 1) { | ||||
|             //             bullet.css("font-size", "4px"); | ||||
|             //         } | ||||
|             //     } else if (i === bcStart + 1) { | ||||
|             //         if (i > 2) { | ||||
|             //             bullet.css("font-size", "4px"); | ||||
|             //         } | ||||
|             //     } | ||||
|             //     if (i === bcEnd - 1) { | ||||
|             //         if (i < state.count - 2) { | ||||
|             //             bullet.css("font-size", "3px"); | ||||
|             //         } else if (i === state.count - 2) { | ||||
|             //             bullet.css("font-size", "4px"); | ||||
|             //         } | ||||
|             //     } else if (i === bcEnd - 2) { | ||||
|             //         if (i < state.count - 3) { | ||||
|             //             bullet.css("font-size", "4px"); | ||||
|             //         } | ||||
|             //     } | ||||
|             //     // if (i === bcEnd - 1) { | ||||
|             //     //     if (i < state.count - 2) { | ||||
|             //     //         bullet.css("font-size", "3px"); | ||||
|             //     //     } else if (i === state.count - 2) { | ||||
|             //     //         bullet.css("font-size", "4px"); | ||||
|             //     //     } | ||||
|             //     // } | ||||
|             // } | ||||
|  | ||||
|             $('<small>').text((state.index+1)+"/"+state.count).appendTo(stepToolbar) | ||||
|             if (fullscreen || !step.wait) { | ||||
|                 var nextButton = $('<button type="button" class="red-ui-button" style="position: absolute; right:0;bottom:0;"></button>').appendTo(stepToolbar).click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     stepEventListener(); | ||||
|                 }); | ||||
|                 if (state.index === state.count - 1) { | ||||
|                     $('<span>close</span>').appendTo(nextButton); | ||||
|                 } else if (state.index === 0) { | ||||
|                     $('<span>start</span>').appendTo(nextButton); | ||||
|                 } else if (state.index < state.count-1) { | ||||
|                     $('<span>next <i class="fa fa-chevron-right"></i></span>').appendTo(nextButton); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             var width = step.width; | ||||
|             if (fullscreen) { | ||||
|                 width = 500; | ||||
|             } | ||||
|             var maxWidth = Math.max(width || 0, 300); | ||||
|             if (!popover) { | ||||
|                 popover = RED.popover.create({ | ||||
|                     target: targetElement, | ||||
|                     width: width || "auto", | ||||
|                     maxWidth: maxWidth+"px", | ||||
|                     direction: direction, | ||||
|                     class: "red-ui-tourGuide-popover"+(fullscreen?" ":""), | ||||
|                     trigger: "manual", | ||||
|                     content: stepContent | ||||
|                 }).open(); | ||||
|             } | ||||
|             popover.element.toggleClass("red-ui-tourGuide-popover-full",!!fullscreen); | ||||
|             popover.move({ | ||||
|                 target: targetElement, | ||||
|                 width: width || "auto", | ||||
|                 maxWidth: maxWidth+"px", | ||||
|                 direction: direction, | ||||
|             }) | ||||
|  | ||||
|  | ||||
|             var isSVG = targetElement[0] instanceof SVGElement; | ||||
|             if (step.fallback) { | ||||
|                 focus.one("mouseenter", function(evt) { | ||||
|                     setTimeout(function() { | ||||
|                         focus.css({ | ||||
|                             width: (4*dimension)+"px", | ||||
|                             height: (4*dimension)+"px" | ||||
|                         }) | ||||
|                         shade.fadeOut(); | ||||
|                         popover.move({ | ||||
|                             target: $(".red-ui-editor"), | ||||
|                             direction: step.fallback, | ||||
|                             offset: 10, | ||||
|                             transition: true | ||||
|                         }) | ||||
|                         // popover.element.addClass('red-ui-tourGuide-popover-bounce'); | ||||
|                     },isSVG?0:500); | ||||
|                 }) | ||||
|             } | ||||
|  | ||||
|             var stepEventListener = function() { | ||||
|                 focus.removeClass("transition"); | ||||
|                 targetElement.css("z-index",zIndex); | ||||
|                 completeStep(step, state, done); | ||||
|             } | ||||
|  | ||||
|             if (step.wait) { | ||||
|                 if (step.wait.type === "dom-event") { | ||||
|                     var eventTarget = targetElement; | ||||
|                     if (step.wait.element) { | ||||
|                         if (typeof step.wait.element === "string") { | ||||
|                             eventTarget = $(step.wait.element); | ||||
|                         } else if (typeof step.wait.element === "function") { | ||||
|                             eventTarget = step.wait.element.call(state); | ||||
|                         } | ||||
|                     } | ||||
|                     var listener = { | ||||
|                         type: step.wait.type, | ||||
|                         target: eventTarget, | ||||
|                         event: step.wait.event, | ||||
|                         listener: function() { | ||||
|                             stepEventListener(); | ||||
|                         }, | ||||
|                         opts: { once: true } | ||||
|                     } | ||||
|                     activeListeners.push(listener) | ||||
|                     eventTarget[0].addEventListener(listener.event,listener.listener,listener.opts) | ||||
|                 } else if (step.wait.type === "nr-event") { | ||||
|                     var listener = { | ||||
|                         type: step.wait.type, | ||||
|                         event: step.wait.event, | ||||
|                         listener: function() { | ||||
|                             if (step.wait.filter) { | ||||
|                                 if (!step.wait.filter.apply(state,arguments)) { | ||||
|                                     return; | ||||
|                                 } | ||||
|                             } | ||||
|                             stepEventListener(); | ||||
|                         } | ||||
|                     } | ||||
|                     activeListeners.push(listener); | ||||
|                     RED.events.on(listener.event,listener.listener); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         run: run | ||||
|     } | ||||
|  | ||||
|  | ||||
| })(); | ||||
| @@ -295,6 +295,10 @@ $group-default-stroke: #999; | ||||
| $group-default-stroke-opacity: 1; | ||||
| $group-default-label-color: #a4a4a4; | ||||
|  | ||||
| $tourGuide-shade: rgba(100, 70, 70, 0.6); | ||||
| $tourGuide-border: #a22222; | ||||
| $tourGuide-heading-color: #a22222; | ||||
|  | ||||
| // Deprecated | ||||
| $text-color-green: $text-color-success; | ||||
| $info-text-code-color: $text-color-code; | ||||
|   | ||||
| @@ -69,3 +69,5 @@ | ||||
| @import "debug"; | ||||
|  | ||||
| @import "radialMenu"; | ||||
|  | ||||
| @import "tourGuide"; | ||||
|   | ||||
							
								
								
									
										122
									
								
								packages/node_modules/@node-red/editor-client/src/sass/tourGuide.scss
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								packages/node_modules/@node-red/editor-client/src/sass/tourGuide.scss
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| .red-ui-tourGuide-shade { | ||||
|     position: absolute; | ||||
|     top:0; | ||||
|     left:0; | ||||
|     bottom:0; | ||||
|     right:0; | ||||
|     z-index: 2000; | ||||
|     overflow: hidden; | ||||
| } | ||||
|  | ||||
| .red-ui-tourGuide-shade-focus { | ||||
|     display: block; | ||||
|     width: 100px; | ||||
|     height: 100px; | ||||
|     position: absolute; | ||||
|     z-index: 2001; | ||||
|     transform: translate(-50%, -50%); | ||||
|     border-radius: 50%; | ||||
|     border: 2px solid $tourGuide-border; | ||||
|  | ||||
|     &.transition { | ||||
|         transition: 0.4s ease; | ||||
|         transition-property: width,height; | ||||
|     } | ||||
|  | ||||
|     &.disableInteraction { | ||||
|         pointer-events: none; | ||||
|     } | ||||
|  | ||||
|     &::before { | ||||
|         content: ''; | ||||
|         position: absolute; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         border-radius: 50%; | ||||
|         border: solid 6000px $tourGuide-shade; | ||||
|         margin-left: -6000px; | ||||
|         margin-top: -6000px; | ||||
|         pointer-events: none; | ||||
|     } | ||||
| } | ||||
| .red-ui-popover.red-ui-tourGuide-popover { | ||||
|     z-index: 2003; | ||||
|     --red-ui-popover-background: #{$secondary-background}; | ||||
|     --red-ui-popover-border: #{$tourGuide-border}; | ||||
|     --red-ui-popover-color: #{$primary-text-color}; | ||||
|  | ||||
|     .red-ui-popover-content { | ||||
|         h2 { | ||||
|             text-align: center; | ||||
|             margin-top: 0px; | ||||
|             color: #a22222; | ||||
|             i.fa { | ||||
|                 font-size: 1.5em | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| .red-ui-tourGuide-toolbar { | ||||
|     min-height: 36px; | ||||
|     position: relative; | ||||
|     display: flex; | ||||
|     align-items: flex-end; | ||||
| } | ||||
| .red-ui-tourGuide-breadcrumbs { | ||||
|     flex-grow: 1; | ||||
|  | ||||
|     display:  flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     font-size: 6px; | ||||
|     & > div { | ||||
|         display: inline-block; | ||||
|     } | ||||
|     i { | ||||
|         line-height: 16px; | ||||
|         margin: 0 3px; | ||||
|     } | ||||
| } | ||||
| .red-ui-tourGuide-popover-description { | ||||
|     padding: 10px 20px 5px; | ||||
| } | ||||
| .red-ui-tourGuide-popover-full { | ||||
|     .red-ui-tourGuide-popover-description { | ||||
|         padding: 20px 40px 10px; | ||||
|         text-align: center; | ||||
|     } | ||||
| } | ||||
| .red-ui-popover.red-ui-tourGuide-popover button.red-ui-button { | ||||
|     &:not(.primary) { | ||||
|         border-color: transparent; | ||||
|         background: $secondary-background; | ||||
|         color: $primary-text-color !important; | ||||
|     } | ||||
|     &:not(.primary):not(.disabled):not(.ui-button-disabled):hover { | ||||
|         border-color: $popover-button-border-color-hover; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| // .red-ui-tourGuide-popover-bounce { | ||||
| //     animation: 10s ease-in 5s infinite both red-ui-tourGuide-popover-bounce; | ||||
| // } | ||||
| // // @keyframes *must* be on multiple lines so build-custom-theme can filter them out | ||||
| // @keyframes red-ui-tourGuide-popover-bounce { | ||||
| //     0%, | ||||
| //     10%, | ||||
| //     100% { | ||||
| //         -webkit-transform: translateY(0); | ||||
| //         transform: translateY(0); | ||||
| //     } | ||||
| //     2%,8% { | ||||
| //         -webkit-transform: translateY(-5px); | ||||
| //         transform: translateY(-5px); | ||||
| //     } | ||||
| //     5% { | ||||
| //         -webkit-transform: translateY(5px); | ||||
| //         transform: translateY(5px); | ||||
| //     } | ||||
| // } | ||||
							
								
								
									
										80
									
								
								packages/node_modules/@node-red/editor-client/src/tours/first-flow.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								packages/node_modules/@node-red/editor-client/src/tours/first-flow.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| export default { | ||||
|     steps: [ | ||||
|         { | ||||
|             title: "Create your first flow", | ||||
|             width: 400, | ||||
|             description: 'This tutorial will guide you through creating your first flow', | ||||
|             nextButton: 'start' | ||||
|         }, | ||||
|         { | ||||
|             element: "#red-ui-workspace .red-ui-tab-button.red-ui-tabs-add", | ||||
|             description: 'To add a new tab, click the <i class="fa fa-plus"></i> button', | ||||
|             wait: { | ||||
|                 type: "dom-event", | ||||
|                 event: "click", | ||||
|                 element: "#red-ui-workspace .red-ui-tab-button.red-ui-tabs-add a" | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             element: '.red-ui-palette-node[data-palette-type="inject"]', | ||||
|             direction: 'right', | ||||
|             description: 'The palette lists all of the nodes available to use. Drag a new Inject node into the workspace.', | ||||
|             fallback: 'inset-bottom-right', | ||||
|             wait: { | ||||
|                 type: "nr-event", | ||||
|                 event: "nodes:add", | ||||
|                 filter: function(event) { | ||||
|                     if (event.type === "inject") { | ||||
|                         this.injectNode = event; | ||||
|                         return true; | ||||
|                     } | ||||
|                     return false | ||||
|                 } | ||||
|             }, | ||||
|             complete: function() { | ||||
|                 $('.red-ui-palette-node[data-palette-type="inject"]').css("z-index","auto"); | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             element: '.red-ui-palette-node[data-palette-type="debug"]', | ||||
|             direction: 'right', | ||||
|             description: 'Next, drag a new Debug node into the workspace.', | ||||
|             fallback: 'inset-bottom-right', | ||||
|             wait: { | ||||
|                 type: "nr-event", | ||||
|                 event: "nodes:add", | ||||
|                 filter: function(event) { | ||||
|                     if (event.type === "debug") { | ||||
|                         this.debugNode = event; | ||||
|                         return true; | ||||
|                     } | ||||
|                     return false | ||||
|                 } | ||||
|             }, | ||||
|             complete: function() { | ||||
|                 $('.red-ui-palette-node[data-palette-type="debug"]').css("z-index","auto"); | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             element: function() { return $("#"+this.injectNode.id+" .red-ui-flow-port") }, | ||||
|             description: 'Add a wire from the output of the Inject node to the input of the Debug node', | ||||
|             fallback: 'inset-bottom-right', | ||||
|             wait: { | ||||
|                 type: "nr-event", | ||||
|                 event: "links:add", | ||||
|                 filter: function(event) { | ||||
|                     return  event.source.id === this.injectNode.id && event.target.id === this.debugNode.id; | ||||
|                 } | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             element: "#red-ui-header-button-deploy", | ||||
|             description: 'Deploy your changes so the flow is active in the runtime', | ||||
|             width: 200, | ||||
|             wait: { | ||||
|                 type: "dom-event", | ||||
|                 event: "click" | ||||
|             }, | ||||
|         } | ||||
|     ] | ||||
| } | ||||
							
								
								
									
										69
									
								
								packages/node_modules/@node-red/editor-client/src/tours/welcome-2-1.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								packages/node_modules/@node-red/editor-client/src/tours/welcome-2-1.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| export default { | ||||
|     steps: [ | ||||
|         { | ||||
|             titleIcon: "fa fa-map-o", | ||||
|             title: "Welcome to Node-RED 2.1!", | ||||
|             description: "Let's take a moment to discover the new features in this release." | ||||
|         }, | ||||
|         { | ||||
|             title: "A new Tour Guide", | ||||
|             description: "<p>First, as you've already found, we now have this tour of new features. We'll only show the tour the first time you open the editor for each new version of Node-RED.</p>"+ | ||||
|                          "<p>You can choose not to see this tour in the future by disabling it under the View tab of User Settings.</p>", | ||||
|         }, | ||||
|         { | ||||
|             prepare:function() { | ||||
|                 $("#red-ui-header-button-sidemenu").trigger("click"); | ||||
|                 $("#menu-item-edit-menu").parent().addClass("open") | ||||
|             }, | ||||
|             complete: function() { | ||||
|                 $("#menu-item-edit-menu").parent().removeClass("open") | ||||
|             }, | ||||
|             element: "#menu-item-edit-menu-submenu", | ||||
|             interactive: false, | ||||
|             direction: "left", | ||||
|             title: "New Edit menu", | ||||
|             description: "<p>The main menu has been updated with a new 'Edit' section. This includes all of the familar options, like cut/paste and undo/redo.</p>"+ | ||||
|                          "<p>The menu now displays keyboard shortcuts for the options.</p>" | ||||
|  | ||||
|         }, | ||||
|         { | ||||
|             prepare: function() { | ||||
|                 $("#red-ui-header-button-sidemenu").trigger("click"); | ||||
|                 $("#menu-item-arrange-menu").parent().addClass("open") | ||||
|             }, | ||||
|             complete: function() { | ||||
|                 $("#menu-item-arrange-menu").parent().removeClass("open") | ||||
|             }, | ||||
|             element: "#menu-item-arrange-menu-submenu", | ||||
|             interactive: false, | ||||
|             direction: "left", | ||||
|             title: "Arranging nodes", | ||||
|             description: "<p>The new 'Arrange' section of the menu provides new options to help arrange your nodes. You can align them to a common edge, spread them out evenly or change their order.</p>", | ||||
|         }, | ||||
|         { | ||||
|             element: "#red-ui-workspace-tabs > li:first-child", | ||||
|             title: "Flow and Group level environment variables", | ||||
|             description: "<p>Flows and Groups can now have their own environment variables that can be referenced by nodes inside them.</p>", | ||||
|         }, | ||||
|         { | ||||
|             prepare: function(done) { | ||||
|                 RED.editor.editFlow(RED.nodes.workspace(RED.workspaces.active()),"editor-tab-envProperties"); | ||||
|                 setTimeout(done,800); | ||||
|             }, | ||||
|             element: "#red-ui-tab-editor-tab-envProperties-link-button", | ||||
|             description: "<p>Flows and Groups now have an Environment Variables section in their edit dialog.</p>" | ||||
|         }, | ||||
|         { | ||||
|             element: ".node-input-env-container-row .red-ui-editableList-addButton", | ||||
|             direction: "top", | ||||
|             description: '<p>The environment variables are listed in this table and new ones can be added by clicking the <i class="fa fa-plus"></i> button.</p>', | ||||
|             complete: function() { | ||||
|                 $("#node-dialog-cancel").trigger("click"); | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             title: "And that's not all...", | ||||
|             description: "<p>There's more still to come before 2.1.0 is released. Watch this space!</p>" | ||||
|         }, | ||||
|     ] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user