mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add initial tour-guide feature
This commit is contained in:
parent
adadf38b08
commit
48baac916c
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/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/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/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"
|
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']
|
tasks: ['jsonlint:keymaps','copy:build']
|
||||||
},
|
},
|
||||||
|
tours: {
|
||||||
|
files: [
|
||||||
|
'packages/node_modules/@node-red/editor-client/src/tours/**/*.js'
|
||||||
|
],
|
||||||
|
tasks: ['copy:build']
|
||||||
|
},
|
||||||
misc: {
|
misc: {
|
||||||
files: [
|
files: [
|
||||||
'CHANGELOG.md'
|
'CHANGELOG.md'
|
||||||
@ -423,6 +430,12 @@ module.exports = function(grunt) {
|
|||||||
src: '**',
|
src: '**',
|
||||||
expand: true,
|
expand: true,
|
||||||
dest: 'packages/node_modules/@node-red/editor-client/public/vendor/ace/'
|
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-stroke-opacity: 1;
|
||||||
$group-default-label-color: #a4a4a4;
|
$group-default-label-color: #a4a4a4;
|
||||||
|
|
||||||
|
$tourGuide-shade: rgba(100, 70, 70, 0.6);
|
||||||
|
$tourGuide-border: #a22222;
|
||||||
|
$tourGuide-heading-color: #a22222;
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
$text-color-green: $text-color-success;
|
$text-color-green: $text-color-success;
|
||||||
$info-text-code-color: $text-color-code;
|
$info-text-code-color: $text-color-code;
|
||||||
|
@ -69,3 +69,5 @@
|
|||||||
@import "debug";
|
@import "debug";
|
||||||
|
|
||||||
@import "radialMenu";
|
@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>"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user