Start on work towards the tutorial. Note that this code is BROKEN
This commit is contained in:
parent
a049fc57c6
commit
dbed1300ad
14 changed files with 338 additions and 63 deletions
|
@ -63,6 +63,12 @@ def guide():
|
||||||
return index('')
|
return index('')
|
||||||
|
|
||||||
|
|
||||||
|
@web.route('/tutorial/')
|
||||||
|
@no_cache
|
||||||
|
def tutorial():
|
||||||
|
return index('')
|
||||||
|
|
||||||
|
|
||||||
@web.route('/organizations/')
|
@web.route('/organizations/')
|
||||||
@web.route('/organizations/new/')
|
@web.route('/organizations/new/')
|
||||||
@no_cache
|
@no_cache
|
||||||
|
|
|
@ -2705,32 +2705,162 @@ p.editable:hover i {
|
||||||
|
|
||||||
/*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
.angular-tour-overlay-element {
|
.angular-tour-ui-element.overlay {
|
||||||
display: block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
left: 20px;
|
|
||||||
right: 20px;
|
right: 20px;
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
color: white;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
z-index: 9999999;
|
z-index: 9999999;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
-webkit-box-shadow: 0 5px 15px rgba(0,0,0,0.5);
|
||||||
|
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
transition: opacity 750ms ease-in-out;
|
transition: opacity 750ms ease-in-out;
|
||||||
-webkit-transition: opacity 750ms ease-in-out;
|
-webkit-transition: opacity 750ms ease-in-out;
|
||||||
|
|
||||||
|
min-width: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.angular-tour-overlay-element.touring {
|
.angular-tour-ui-element.overlay.touring {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.angular-tour-overlay-element.nottouring {
|
.angular-tour-ui-element.overlay.nottouring {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -10000px;
|
left: -10000px;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
height: 0px;
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .tour-title {
|
||||||
|
background: #778EA2;
|
||||||
|
color: white;
|
||||||
|
padding: 4px;
|
||||||
|
padding-left: 6px;
|
||||||
|
padding-right: 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-bottom-left-radius: 0px;
|
||||||
|
border-bottom-right-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .tour-title h4 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .step-title {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .step-content {
|
||||||
|
padding: 10px;
|
||||||
|
padding-left: 0px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .tour-contents {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .controls {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .controls .btn {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.angular-tour-ui-element.overlay .fa {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline {
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline .fa-dot-circle-o {
|
||||||
|
font-size: 34px;
|
||||||
|
background: #ddd;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline .tour-title h4 {
|
||||||
|
font-size: 28px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline .tour-title .close {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline .step-title {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline .step-content {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element.inline .controls {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element p {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element .wait-message {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element .wait-message .quay-spinner {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.angular-tour-ui-element .wait-message .quay-spinner .small-spinner {
|
||||||
|
border-top-color: #999;
|
||||||
|
border-left-color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.command {
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
text-shadow: none;
|
||||||
|
overflow: auto;
|
||||||
|
border: solid 1px #ccc;
|
||||||
|
position: relative;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.command:before {
|
||||||
|
content: "\f120";
|
||||||
|
font-family: "FontAwesome";
|
||||||
|
font-size: 16px;
|
||||||
|
margin-right: 6px;
|
||||||
|
color: #999;
|
||||||
}
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
<div class="angular-tour-overlay-element" ng-class="tour ? 'touring' : 'nottouring'">
|
|
||||||
<span class="tour-title">{{ tour.title }}</span>
|
|
||||||
<span class="step-title">{{ step.title }}</span>
|
|
||||||
<span class="step-content">{{ step.content }}</span>
|
|
||||||
|
|
||||||
<span class="controls">
|
|
||||||
<button ng-click="next()" ng-show="hasNextStep && !step.signal">Next</button>
|
|
||||||
<button ng-click="stop()" ng-show="!hasNextStep">Done</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
27
static/directives/angular-tour-ui.html
Normal file
27
static/directives/angular-tour-ui.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<div class="angular-tour-ui-element"
|
||||||
|
ng-class="[tour ? 'touring' : 'nottouring', inline ? 'inline' : 'overlay']">
|
||||||
|
|
||||||
|
<div class="tour-title">
|
||||||
|
<h4><i class="fa fa-dot-circle-o"></i> {{ tour.title }}</h4>
|
||||||
|
<button type="button" class="close" ng-click="stop()" aria-hidden="true">×</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tour-contents">
|
||||||
|
<div class="step-title" ng-shpw="step.title">{{ step.title }}</div>
|
||||||
|
<div class="slide-animate-container">
|
||||||
|
<div class="step-content" ng-show="step.content" ng-bind-html="step.content || ''"></div>
|
||||||
|
<div class="step-content">
|
||||||
|
<ng:include src="step.templateUrl" scope="info"></ng:include>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button class="btn btn-primary" ng-click="next()" ng-show="hasNextStep && !step.signal">Next</button>
|
||||||
|
<button class="btn btn-primary" ng-click="stop()" ng-show="!hasNextStep && !inline">Done</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wait-message" ng-show="step.waitMessage">
|
||||||
|
<div class="quay-spinner"></div> {{ step.waitMessage }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -16,6 +16,7 @@
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li><a ng-href="/repository/" target="{{ appLinkTarget() }}">Repositories</a></li>
|
<li><a ng-href="/repository/" target="{{ appLinkTarget() }}">Repositories</a></li>
|
||||||
<li><a ng-href="/guide/" target="{{ appLinkTarget() }}">Guide</a></li>
|
<li><a ng-href="/guide/" target="{{ appLinkTarget() }}">Guide</a></li>
|
||||||
|
<li><a ng-href="/tutorial/" target="{{ appLinkTarget() }}">Tutorial</a></li>
|
||||||
<li><a ng-href="/plans/" target="{{ appLinkTarget() }}">Pricing</a></li>
|
<li><a ng-href="/plans/" target="{{ appLinkTarget() }}">Pricing</a></li>
|
||||||
<li><a ng-href="/organizations/" target="{{ appLinkTarget() }}">Organizations</a></li>
|
<li><a ng-href="/organizations/" target="{{ appLinkTarget() }}">Organizations</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -771,6 +771,8 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
|
||||||
reloadOnSearch: false, controller: UserAdminCtrl}).
|
reloadOnSearch: false, controller: UserAdminCtrl}).
|
||||||
when('/guide/', {title: 'Guide', description:'Guide to using private docker repositories on Quay.io', templateUrl: '/static/partials/guide.html',
|
when('/guide/', {title: 'Guide', description:'Guide to using private docker repositories on Quay.io', templateUrl: '/static/partials/guide.html',
|
||||||
controller: GuideCtrl}).
|
controller: GuideCtrl}).
|
||||||
|
when('/tutorial/', {title: 'Tutorial', description:'Interactive tutorial for using Quay.io', templateUrl: '/static/partials/tutorial.html',
|
||||||
|
controller: TutorialCtrl}).
|
||||||
when('/contact/', {title: 'Contact Us', description:'Different ways for you to get a hold of us when you need us most.', templateUrl: '/static/partials/contact.html',
|
when('/contact/', {title: 'Contact Us', description:'Different ways for you to get a hold of us when you need us most.', templateUrl: '/static/partials/contact.html',
|
||||||
controller: ContactCtrl}).
|
controller: ContactCtrl}).
|
||||||
when('/plans/', {title: 'Plans and Pricing', description: 'Plans and pricing for private docker repositories on Quay.io',
|
when('/plans/', {title: 'Plans and Pricing', description: 'Plans and pricing for private docker repositories on Quay.io',
|
||||||
|
|
|
@ -42,35 +42,62 @@ function PlansCtrl($scope, $location, UserService, PlanService) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function GuideCtrl($scope, AngularTour, AngularTourSignals) {
|
function GuideCtrl($scope) {
|
||||||
$scope.startTour = function() {
|
}
|
||||||
AngularTour.start({
|
|
||||||
'title': 'My Test Tour',
|
function TutorialCtrl($scope, AngularTour, AngularTourSignals, UserService) {
|
||||||
'steps': [
|
$scope.tour = {
|
||||||
{
|
'title': 'Quay.io Tutorial',
|
||||||
'title': 'Welcome to the tour!',
|
'steps': [
|
||||||
'content': 'Some cool content'
|
{
|
||||||
},
|
'title': 'Welcome to the Quay.io tutorial!',
|
||||||
{
|
'templateUrl': '/static/tutorial/welcome.html'
|
||||||
'title': 'A step tied to a DOM element',
|
},
|
||||||
'content': 'This is the best DOM element!',
|
{
|
||||||
'element': '#test-element'
|
'title': 'Sign in to get started',
|
||||||
},
|
'templateUrl': '/static/tutorial/signup.html',
|
||||||
{
|
'signal': function($tourScope) {
|
||||||
'content': 'Waiting for the page to change',
|
$tourScope.username = UserService.currentUser().username;
|
||||||
'signal': AngularTourSignals.matchesLocation('/repository/')
|
$tourScope.email = UserService.currentUser().email;
|
||||||
},
|
return !UserService.currentUser().anonymous;
|
||||||
{
|
|
||||||
'content': 'Waiting for the page to load',
|
|
||||||
'signal': AngularTourSignals.elementAvaliable('*[data-repo="public/publicrepo"]')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'content': 'Now click on the public repository',
|
|
||||||
'signal': AngularTourSignals.matchesLocation('/repository/public/publicrepo'),
|
|
||||||
'element': '*[data-repo="public/publicrepo"]'
|
|
||||||
}
|
}
|
||||||
]
|
},
|
||||||
});
|
{
|
||||||
|
'title': 'Step 1: Login to Quay.io',
|
||||||
|
'templateUrl': '/static/tutorial/docker-login.html',
|
||||||
|
'signal': AngularTourSignals.matchesLocation('/repository/'),
|
||||||
|
'waitMessage': "Waiting for login"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Step 2: Create a new image',
|
||||||
|
'templateUrl': '/static/tutorial/create-image.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Step 3: Push the image to Quay.io',
|
||||||
|
'templateUrl': '/static/tutorial/push-image.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Step 4: View the repository on Quay.io',
|
||||||
|
'templateUrl': '/static/tutorial/view-repo.html',
|
||||||
|
'signal': AngularTourSignals.matchesLocation('/repository/'),
|
||||||
|
'waitMessage': "Waiting for image push to complete"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'content': 'Waiting for the page to load',
|
||||||
|
'signal': AngularTourSignals.elementAvaliable('*[data-repo="{{username}}/{{repoName}}"]'),
|
||||||
|
'overlayable': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'content': 'Select your new repository from the list',
|
||||||
|
'signal': AngularTourSignals.matchesLocation('/repository/{{username}}/{{repoName}}'),
|
||||||
|
'element': '*[data-repo="{{username}}/{{repoName}}"]',
|
||||||
|
'overlayable': true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'content': 'And done!',
|
||||||
|
'overlayable': true
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
angular.module("angular-tour", [])
|
angular.module("angular-tour", [])
|
||||||
.provider('AngularTour', function() {
|
.provider('AngularTour', function() {
|
||||||
this.$get = ['$document', '$rootScope', '$compile', function($document, $rootScope, $compile) {
|
this.$get = ['$document', '$rootScope', '$compile', '$location', function($document, $rootScope, $compile, $location) {
|
||||||
function _start(tour) {
|
$rootScope.angular_tour_current = null;
|
||||||
|
|
||||||
|
function _start(tour, opt_stepIndex, opt_existingScope) {
|
||||||
|
tour.initialStep = opt_stepIndex || tour.initialStep || 0;
|
||||||
|
tour.tourScope = opt_existingScope || null;
|
||||||
$rootScope.angular_tour_current = tour;
|
$rootScope.angular_tour_current = tour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,24 +17,53 @@ angular.module("angular-tour", [])
|
||||||
start: _start,
|
start: _start,
|
||||||
stop: _stop
|
stop: _stop
|
||||||
};
|
};
|
||||||
|
|
||||||
}];
|
}];
|
||||||
})
|
})
|
||||||
|
|
||||||
.directive('angularTourOverlay', function() {
|
.directive('angularTourUi', function() {
|
||||||
var directiveDefinitionObject = {
|
var directiveDefinitionObject = {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
templateUrl: '/static/directives/angular-tour-overlay.html',
|
templateUrl: '/static/directives/angular-tour-ui.html',
|
||||||
replace: false,
|
replace: false,
|
||||||
transclude: false,
|
transclude: false,
|
||||||
restrict: 'C',
|
restrict: 'C',
|
||||||
scope: {
|
scope: {
|
||||||
'tour': '=tour'
|
'tour': '=tour',
|
||||||
|
'inline': '=inline',
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, $interval) {
|
controller: function($rootScope, $scope, $element, $location, $interval, AngularTour) {
|
||||||
|
var createNewScope = function() {
|
||||||
|
var tourScope = {
|
||||||
|
'_replaceData': function(s) {
|
||||||
|
if (typeof s != 'string') {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var key in tourScope) {
|
||||||
|
if (key[0] == '_') { continue; }
|
||||||
|
if (tourScope.hasOwnProperty(key)) {
|
||||||
|
s = s.replace('{{' + key + '}}', tourScope[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return tourScope;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.stepIndex = 0;
|
$scope.stepIndex = 0;
|
||||||
$scope.step = null;
|
$scope.step = null;
|
||||||
$scope.interval = null;
|
$scope.interval = null;
|
||||||
|
$scope.tourScope = createNewScope();
|
||||||
|
|
||||||
|
var getElement = function() {
|
||||||
|
if (typeof $scope.step['element'] == 'function') {
|
||||||
|
return $($scope.step['element'](tourScope));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $($scope.tourScope._replaceData($scope.step['element']));
|
||||||
|
};
|
||||||
|
|
||||||
var checkSignalTimer = function() {
|
var checkSignalTimer = function() {
|
||||||
if (!$scope.step) {
|
if (!$scope.step) {
|
||||||
|
@ -38,8 +71,8 @@ angular.module("angular-tour", [])
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var signal = $scope.step.signal;
|
var signal = $scope.step['signal'];
|
||||||
if (signal()) {
|
if (signal($scope.tourScope)) {
|
||||||
$scope.next();
|
$scope.next();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -58,12 +91,12 @@ angular.module("angular-tour", [])
|
||||||
var closeDomHighlight = function() {
|
var closeDomHighlight = function() {
|
||||||
if (!$scope.step) { return; }
|
if (!$scope.step) { return; }
|
||||||
|
|
||||||
var element = $($scope.step.element);
|
var element = getElement($scope.tourScope);
|
||||||
element.spotlight('close');
|
element.spotlight('close');
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateDomHighlight = function() {
|
var updateDomHighlight = function() {
|
||||||
var element = $($scope.step.element);
|
var element = getElement();
|
||||||
if (!element.length) {
|
if (!element.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +127,13 @@ angular.module("angular-tour", [])
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.step = $scope.tour.steps[stepIndex];
|
$scope.step = $scope.tour.steps[stepIndex];
|
||||||
|
|
||||||
|
// If the signal is already true, then skip this step entirely.
|
||||||
|
if ($scope.step['signal'] && $scope.step['signal']($scope.tourScope)) {
|
||||||
|
$scope.setStepIndex(stepIndex + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.stepIndex = stepIndex;
|
$scope.stepIndex = stepIndex;
|
||||||
$scope.hasNextStep = stepIndex < $scope.tour.steps.length - 1;
|
$scope.hasNextStep = stepIndex < $scope.tour.steps.length - 1;
|
||||||
|
|
||||||
|
@ -110,7 +150,9 @@ angular.module("angular-tour", [])
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.stop = function() {
|
$scope.stop = function() {
|
||||||
|
closeDomHighlight();
|
||||||
$scope.tour = null;
|
$scope.tour = null;
|
||||||
|
AngularTour.stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.next = function() {
|
$scope.next = function() {
|
||||||
|
@ -119,8 +161,35 @@ angular.module("angular-tour", [])
|
||||||
|
|
||||||
$scope.$watch('tour', function(tour) {
|
$scope.$watch('tour', function(tour) {
|
||||||
stopSignalTimer();
|
stopSignalTimer();
|
||||||
$scope.setStepIndex(0);
|
if (tour) {
|
||||||
|
$scope.setStepIndex(tour.initialStep || 0);
|
||||||
|
$scope.tourScope = tour.tourScope || createNewScope();
|
||||||
|
$scope.tour.tourScope = $scope.tourScope;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If this is an inline tour, then we need to monitor the page to determine when
|
||||||
|
// to transition it to an overlay tour.
|
||||||
|
if ($scope.inline) {
|
||||||
|
var counter = 0;
|
||||||
|
var unbind = $rootScope.$watch(function() {
|
||||||
|
return $location.path();
|
||||||
|
}, function(location) {
|
||||||
|
// Since this callback fires for the first page display, we only unbind it
|
||||||
|
// after the second call.
|
||||||
|
if (counter == 1) {
|
||||||
|
// Unbind the listener.
|
||||||
|
unbind();
|
||||||
|
|
||||||
|
// If there is an active tour, transition it over to the overlay.
|
||||||
|
if ($scope.tour && $scope.step && $scope.step['overlayable']) {
|
||||||
|
AngularTour.start($scope.tour, $scope.stepIndex, $scope.tourScope);
|
||||||
|
$scope.tour = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return directiveDefinitionObject;
|
return directiveDefinitionObject;
|
||||||
|
@ -131,15 +200,15 @@ angular.module("angular-tour", [])
|
||||||
|
|
||||||
// Signal: When the page location matches the given path.
|
// Signal: When the page location matches the given path.
|
||||||
signals.matchesLocation = function(locationPath) {
|
signals.matchesLocation = function(locationPath) {
|
||||||
return function() {
|
return function(tourScope) {
|
||||||
return $location.path() == locationPath;
|
return $location.path() == tourScope._replaceData(locationPath);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Signal: When an element is found in the page's DOM.
|
// Signal: When an element is found in the page's DOM.
|
||||||
signals.elementAvaliable = function(elementPath) {
|
signals.elementAvaliable = function(elementPath) {
|
||||||
return function() {
|
return function(tourScope) {
|
||||||
return $(elementPath).length > 0;
|
return $(tourScope._replaceData(elementPath)).length > 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
3
static/partials/tutorial.html
Normal file
3
static/partials/tutorial.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="container">
|
||||||
|
<div class="angular-tour-ui" tour="tour" inline="true"></div>
|
||||||
|
</div>
|
8
static/tutorial/docker-login.html
Normal file
8
static/tutorial/docker-login.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="container">
|
||||||
|
<p>The first step when using Quay.io is to login via the <code>docker login</code> command.</p>
|
||||||
|
<p>Enter your Quay.io username and your password when prompted.</p>
|
||||||
|
<pre class="command">docker login quay.io
|
||||||
|
Username: {{ tour.tourScope.username }}
|
||||||
|
Password: (password here)
|
||||||
|
Email: {{ tour.tourScope.email }}</pre>
|
||||||
|
</div>
|
11
static/tutorial/signup.html
Normal file
11
static/tutorial/signup.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<div class="container signin-container">
|
||||||
|
<div class="row" style="margin-bottom: 10px">
|
||||||
|
This tutorial will interact with your account, so please sign in to get started
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 col-sm-offset-3">
|
||||||
|
<div class="user-setup" redirect-url="'/tutorial/'"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
1
static/tutorial/welcome.html
Normal file
1
static/tutorial/welcome.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This tutorial will walk you step-by-step through using Quay.io, including pushing/pulling repositories, making permissions changes and managing your repository.
|
|
@ -171,6 +171,6 @@ var isProd = document.location.hostname === 'quay.io';
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<!-- end olark code -->
|
<!-- end olark code -->
|
||||||
|
|
||||||
<div class="angular-tour-overlay" tour="angular_tour_current"></div>
|
<div class="angular-tour-ui" inline="false" tour="angular_tour_current"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Binary file not shown.
Reference in a new issue