From 944d08dcb7bd90e851797a38a56a6f0db4b6a42d Mon Sep 17 00:00:00 2001 From: Volodymyr Tymtsiv Date: Mon, 17 Sep 2018 20:52:22 +0300 Subject: [PATCH 01/27] Add Shepherd library. Add 'Services' tutorial. --- .../adf-services/dreamfactory-services.js | 4 + .../views/df-manage-services.html | 2 +- .../adf-services/views/df-service-info.html | 2 +- .../adf-tutorial/app-tutorial.directive.js | 18 +++ .../service-tutorial.directive.js | 79 ++++++++++ .../adf-tutorial/tutorial.controller.js | 23 +++ .../adf-tutorial/tutorial.module.js | 22 +++ .../adf-tutorial/views/app-tutorial.html | 4 + .../adf-tutorial/views/main-tutorial.html | 9 ++ .../adf-tutorial/views/service-tutorial.html | 10 ++ .../adf-utility/views/df-component-nav.html | 5 +- app/index.html | 8 + app/popper.min.js | 5 + app/scripts/app.js | 5 +- app/scripts/controllers/main.js | 8 +- app/shepherd-theme-arrows.css | 144 ++++++++++++++++++ app/shepherd.min.js | 6 + app/styles/sass/styles.css | 16 ++ .../views/df-manage-services.html | 2 +- .../adf-services/views/df-service-info.html | 2 +- .../adf-tutorial/views/app-tutorial.html | 1 + .../adf-tutorial/views/main-tutorial.html | 1 + .../adf-tutorial/views/service-tutorial.html | 1 + .../adf-utility/views/df-component-nav.html | 2 +- dist/index.html | 4 +- dist/scripts/app.8949778b.js | 1 - dist/scripts/app.f5162f5b.js | 1 + dist/styles/styles.90af733d.css | 12 ++ dist/styles/styles.ec4de73b.css | 12 -- 29 files changed, 384 insertions(+), 25 deletions(-) create mode 100644 app/admin_components/adf-tutorial/app-tutorial.directive.js create mode 100644 app/admin_components/adf-tutorial/service-tutorial.directive.js create mode 100644 app/admin_components/adf-tutorial/tutorial.controller.js create mode 100644 app/admin_components/adf-tutorial/tutorial.module.js create mode 100644 app/admin_components/adf-tutorial/views/app-tutorial.html create mode 100644 app/admin_components/adf-tutorial/views/main-tutorial.html create mode 100644 app/admin_components/adf-tutorial/views/service-tutorial.html create mode 100644 app/popper.min.js create mode 100644 app/shepherd-theme-arrows.css create mode 100644 app/shepherd.min.js create mode 100644 dist/admin_components/adf-tutorial/views/app-tutorial.html create mode 100644 dist/admin_components/adf-tutorial/views/main-tutorial.html create mode 100644 dist/admin_components/adf-tutorial/views/service-tutorial.html delete mode 100644 dist/scripts/app.8949778b.js create mode 100644 dist/scripts/app.f5162f5b.js create mode 100644 dist/styles/styles.90af733d.css delete mode 100644 dist/styles/styles.ec4de73b.css diff --git a/app/admin_components/adf-services/dreamfactory-services.js b/app/admin_components/adf-services/dreamfactory-services.js index be49dcc6..425937fd 100644 --- a/app/admin_components/adf-services/dreamfactory-services.js +++ b/app/admin_components/adf-services/dreamfactory-services.js @@ -96,6 +96,10 @@ angular.module('dfServices', ['ngRoute', 'dfUtility']) }; $scope.loadTabData(true); + + $scope.showStep = function () { + Shepherd.activeTour.show('example2'); + } }]) .directive('dfServiceLoading', [function() { diff --git a/app/admin_components/adf-services/views/df-manage-services.html b/app/admin_components/adf-services/views/df-manage-services.html index 92201848..cc1d6d80 100644 --- a/app/admin_components/adf-services/views/df-manage-services.html +++ b/app/admin_components/adf-services/views/df-manage-services.html @@ -22,7 +22,7 @@
-
+
diff --git a/app/admin_components/adf-services/views/df-service-info.html b/app/admin_components/adf-services/views/df-service-info.html index d49b2de5..97d46d61 100644 --- a/app/admin_components/adf-services/views/df-service-info.html +++ b/app/admin_components/adf-services/views/df-service-info.html @@ -21,7 +21,7 @@
-
diff --git a/app/admin_components/adf-tutorial/app-tutorial.directive.js b/app/admin_components/adf-tutorial/app-tutorial.directive.js new file mode 100644 index 00000000..9a57dae3 --- /dev/null +++ b/app/admin_components/adf-tutorial/app-tutorial.directive.js @@ -0,0 +1,18 @@ +'use strict'; + +angular.module('dfTutorial') + + + .directive('dfAppTutorial', ['MOD_TUTORIALS_ASSET_PATH', function (MOD_TUTORIALS_ASSET_PATH) { + + return { + restrict: 'E', + scope: { + apiData: '=?' + }, + templateUrl: MOD_TUTORIALS_ASSET_PATH + 'views/app-tutorial.html', + link: function (scope, elem, attrs) { + + } + }; + }]); \ No newline at end of file diff --git a/app/admin_components/adf-tutorial/service-tutorial.directive.js b/app/admin_components/adf-tutorial/service-tutorial.directive.js new file mode 100644 index 00000000..27ef3515 --- /dev/null +++ b/app/admin_components/adf-tutorial/service-tutorial.directive.js @@ -0,0 +1,79 @@ +'use strict'; + +angular.module('dfTutorial') + + .directive('dfServiceTutorial', ['MOD_TUTORIALS_ASSET_PATH', '$location', function (MOD_TUTORIALS_ASSET_PATH, $location) { + + return { + restrict: 'E', + templateUrl: MOD_TUTORIALS_ASSET_PATH + 'views/service-tutorial.html', + link: function (scope, elem, attrs) { + + + scope.start = function () { + tour.start(); + }; + + var tour = new Shepherd.Tour({ + defaultStepOptions: { + classes: 'shepherd-theme-arrows', + scrollTo: true + } + }); + + tour.addStep('example1', { + title: 'Services Tab', + text: 'Settings related to services.', + attachTo: {element: '.tutorial-step-Services ', on: 'bottom'}, + buttons: [ + + { + text: 'Thanks!', + action: tour.complete + }, + { + text: 'Next', + action: function () { + scope.$apply($location.url('/services')) + } + } + ] + + }) + + tour.addStep('example2', { + title: 'Table with services', + text: 'These are all services in the system.', + attachTo: {element: '.tutorial-table', on: 'bottom'}, + buttons: [ + + { + text: 'Thanks!', + action: tour.complete + }, + { + text: 'Next', + action: function () { + angular.element('#services_table_row_3_1').triggerHandler('click'); + tour.next() + } + } + ] + }) + + tour.addStep('example3', { + title: 'Service type', + text: 'Service type which was selected during service creation.', + attachTo: {element: '.tutorial-dropdown', on: 'bottom'}, + buttons: [ + + { + text: 'Thanks!', + action: tour.complete + } + ] + }) + + } + }; + }]) \ No newline at end of file diff --git a/app/admin_components/adf-tutorial/tutorial.controller.js b/app/admin_components/adf-tutorial/tutorial.controller.js new file mode 100644 index 00000000..7c7e86b4 --- /dev/null +++ b/app/admin_components/adf-tutorial/tutorial.controller.js @@ -0,0 +1,23 @@ +'use strict'; + +angular.module('dfTutorial') + + .controller('TutorialController', ['$scope', function ($scope) { + + $scope.$parent.title = 'Tutorials'; + + $scope.links = [ + { + name: 'service', + label: 'Service', + path: 'service-tutorial' + }, + { + name: 'app', + label: 'App', + path: 'app-tutorial' + } + ]; + }]) + + diff --git a/app/admin_components/adf-tutorial/tutorial.module.js b/app/admin_components/adf-tutorial/tutorial.module.js new file mode 100644 index 00000000..0e3f8f3b --- /dev/null +++ b/app/admin_components/adf-tutorial/tutorial.module.js @@ -0,0 +1,22 @@ +'use strict'; + +angular.module('dfTutorial', []) + .constant('MOD_TUTORIALS_ROUTER_PATH', '/tutorials') + .constant('MOD_TUTORIALS_ASSET_PATH', 'admin_components/adf-tutorial/') + .config(['$routeProvider', 'MOD_TUTORIALS_ROUTER_PATH', 'MOD_TUTORIALS_ASSET_PATH', + function ($routeProvider, MOD_TUTORIALS_ROUTER_PATH, MOD_TUTORIALS_ASSET_PATH) { + $routeProvider + .when(MOD_TUTORIALS_ROUTER_PATH, { + templateUrl: MOD_TUTORIALS_ASSET_PATH + 'views/main-tutorial.html', + controller: 'TutorialController', + resolve: { + checkUser: ['checkUserService', function (checkUserService) { + return checkUserService.checkUser(); + }] + } + }); + }]) + + .run([function () { + + }]) \ No newline at end of file diff --git a/app/admin_components/adf-tutorial/views/app-tutorial.html b/app/admin_components/adf-tutorial/views/app-tutorial.html new file mode 100644 index 00000000..a80dc88a --- /dev/null +++ b/app/admin_components/adf-tutorial/views/app-tutorial.html @@ -0,0 +1,4 @@ + + + +

Will be soon :)

\ No newline at end of file diff --git a/app/admin_components/adf-tutorial/views/main-tutorial.html b/app/admin_components/adf-tutorial/views/main-tutorial.html new file mode 100644 index 00000000..b5c9ab1d --- /dev/null +++ b/app/admin_components/adf-tutorial/views/main-tutorial.html @@ -0,0 +1,9 @@ +
+
+ +
+
+ + +
+
diff --git a/app/admin_components/adf-tutorial/views/service-tutorial.html b/app/admin_components/adf-tutorial/views/service-tutorial.html new file mode 100644 index 00000000..bc62d248 --- /dev/null +++ b/app/admin_components/adf-tutorial/views/service-tutorial.html @@ -0,0 +1,10 @@ + + +
+

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more. + +

+ diff --git a/app/admin_components/adf-utility/views/df-component-nav.html b/app/admin_components/adf-utility/views/df-component-nav.html index 041039cb..fd3c0473 100644 --- a/app/admin_components/adf-utility/views/df-component-nav.html +++ b/app/admin_components/adf-utility/views/df-component-nav.html @@ -1,6 +1,6 @@
-
{{field.label}}
{{value}}
\ No newline at end of file +
{{field.label}}
{{value}}
\ No newline at end of file diff --git a/dist/admin_components/adf-services/views/df-service-info.html b/dist/admin_components/adf-services/views/df-service-info.html index 65a7378a..bddcf1f5 100644 --- a/dist/admin_components/adf-services/views/df-service-info.html +++ b/dist/admin_components/adf-services/views/df-service-info.html @@ -1 +1 @@ -



This feature requires a DreamFactory {{selectedSchema.subscription_required}} product subscription.

Email sales@dreamfactory.com or call +1-415-612-8958 for pricing information.
\ No newline at end of file +



This feature requires a DreamFactory {{selectedSchema.subscription_required}} product subscription.

Email sales@dreamfactory.com or call +1-415-612-8958 for pricing information.
\ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/app-tutorial.html b/dist/admin_components/adf-tutorial/views/app-tutorial.html new file mode 100644 index 00000000..f6705001 --- /dev/null +++ b/dist/admin_components/adf-tutorial/views/app-tutorial.html @@ -0,0 +1 @@ +

Will be soon :) \ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/main-tutorial.html b/dist/admin_components/adf-tutorial/views/main-tutorial.html new file mode 100644 index 00000000..4cf256f4 --- /dev/null +++ b/dist/admin_components/adf-tutorial/views/main-tutorial.html @@ -0,0 +1 @@ +

\ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/service-tutorial.html b/dist/admin_components/adf-tutorial/views/service-tutorial.html new file mode 100644 index 00000000..74a88c60 --- /dev/null +++ b/dist/admin_components/adf-tutorial/views/service-tutorial.html @@ -0,0 +1 @@ +

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more.

\ No newline at end of file diff --git a/dist/admin_components/adf-utility/views/df-component-nav.html b/dist/admin_components/adf-utility/views/df-component-nav.html index df3e3fc6..fc055569 100644 --- a/dist/admin_components/adf-utility/views/df-component-nav.html +++ b/dist/admin_components/adf-utility/views/df-component-nav.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/dist/index.html b/dist/index.html index 4c9cfa5c..5ea0cb43 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,8 +1,8 @@ - DreamFactory
+ + + diff --git a/app/scripts/app.js b/app/scripts/app.js index d2790473..37cbf37e 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -36,7 +36,8 @@ angular 'dfFileManager', 'dfPackageManager', 'dfLimit', - 'dfTutorial' + 'dfTutorial', + 'dfServiceModule' ]) // each tab uses this in its resolve function to make sure user is allowed access diff --git a/app/services/services.module.js b/app/services/services.module.js new file mode 100644 index 00000000..7de2950b --- /dev/null +++ b/app/services/services.module.js @@ -0,0 +1,3 @@ +'use strict'; + +angular.module('dfServiceModule', []); \ No newline at end of file diff --git a/app/services/tutorial-handler.service.js b/app/services/tutorial-handler.service.js new file mode 100644 index 00000000..d138372e --- /dev/null +++ b/app/services/tutorial-handler.service.js @@ -0,0 +1,9 @@ +'use strict'; + +angular + .module('dfServiceModule') + .service('dfTutorialHandler', [function () { + + return {} + + }]); \ No newline at end of file diff --git a/dist/admin_components/adf-services/views/df-service-info.html b/dist/admin_components/adf-services/views/df-service-info.html index bddcf1f5..d1937d03 100644 --- a/dist/admin_components/adf-services/views/df-service-info.html +++ b/dist/admin_components/adf-services/views/df-service-info.html @@ -1 +1 @@ -



This feature requires a DreamFactory {{selectedSchema.subscription_required}} product subscription.

Email sales@dreamfactory.com or call +1-415-612-8958 for pricing information.
\ No newline at end of file +



This feature requires a DreamFactory {{selectedSchema.subscription_required}} product subscription.

Email sales@dreamfactory.com or call +1-415-612-8958 for pricing information.
\ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/service-tutorial.html b/dist/admin_components/adf-tutorial/views/service-tutorial.html index 74a88c60..c6e25410 100644 --- a/dist/admin_components/adf-tutorial/views/service-tutorial.html +++ b/dist/admin_components/adf-tutorial/views/service-tutorial.html @@ -1 +1 @@ -

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more.

\ No newline at end of file +

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more.

\ No newline at end of file diff --git a/dist/index.html b/dist/index.html index 5ea0cb43..07d7fe53 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,8 +1,8 @@ - DreamFactory
- - + diff --git a/app/scripts/app.js b/app/scripts/app.js index e9f04232..37cbf37e 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -120,7 +120,7 @@ angular .constant('APP_VERSION', '2.16.1') // Set global url for this application - .constant('INSTANCE_BASE_URL', '') + .constant('INSTANCE_BASE_URL', 'http://localhost:8000') // Make prefix configurable .constant('INSTANCE_API_PREFIX', '/api/v2') diff --git a/app/services/tutorial-handler.service.js b/app/services/tutorial.service.js similarity index 88% rename from app/services/tutorial-handler.service.js rename to app/services/tutorial.service.js index 1ab0e6d6..786987e1 100644 --- a/app/services/tutorial-handler.service.js +++ b/app/services/tutorial.service.js @@ -2,7 +2,7 @@ angular .module('dfServiceModule') - .service('dfTutorialHandler', [function () { + .service('dfTutorial', [function () { this.showStepAfterViewInit = function (currentStepId, stepToBeShown) { setTimeout(function () { diff --git a/dist/index.html b/dist/index.html index ac1c3522..69901a0e 100644 --- a/dist/index.html +++ b/dist/index.html @@ -2,7 +2,7 @@

You are using an outdated browser. Please upgrade your browser to improve your experience.

+ diff --git a/app/scripts/tour_scenarios/all.js b/app/scripts/tour_scenarios/all.js new file mode 100644 index 00000000..98ab4b3e --- /dev/null +++ b/app/scripts/tour_scenarios/all.js @@ -0,0 +1,610 @@ +var allScenarios = { + createService: { + steps: [ + { + name: 'services-tab', + type: 'click', + options: { + title: 'Services Tab', + text: 'Tab with settings related to services. Let\'s open it.', + attachTo: {element: '.tutorial-step-services-tab', on: 'bottom'}, + advanceOn: {element: '.tutorial-step-services-tab', on: 'click'}, + buttons: [ + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + } + ] + }, + customFunctionObjects: [] + }, + + { + name: 'create-button', + type: 'click', + options: { + title: 'Button to create a service', + text: 'Let\'s create a service. Click on the button.', + attachTo: {element: '.tutorial-step-create-service-button', on: 'bottom'}, + buttons: [ + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + } + ] + }, + customFunctionObjects: [ + { + event: 'show', + handler: + function () { + $('.tutorial-step-create-service-button').on('click', function (event) { + allScenarios.createService.tour.next() + }); + } + } + ] + }, + + { + name: 'selecting-service-type', + type: 'click', + options: { + title: 'Service type', + text: 'Select \'Database\' service type and choose MySQL', + attachTo: {element: '.tutorial-step-selecting-service-type-dropdown', on: 'top'}, + buttons: [ + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + } + ] + }, + customFunctionObjects: [ + { + event: 'show', + handler: + function () { + angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); + + $('.tutorial-step-service-type-selected').on('click', function (event) { + if ($('.tutorial-step-selecting-service-type-dropdown').text().indexOf('MySQL') !== -1) { + allScenarios.createService.tour.next() + } + }); + } + }, + { + event: 'before-hide', + handler: function () { + angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', 'auto;'); + } + + + } + ] + }, + + { + name: 'service-name-input', + type: 'input', + options: { + title: 'Service name', + text: 'Select a name for making API requests, such as \'db\' in /api/v2/db.', + attachTo: {element: '.tutorial-service-name', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + { + text: 'next', + action: function () { + if ($('.tutorial-service-name').val() !== '') { + allScenarios.createService.tour.next() + } + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-label-input', + type: 'input', + options: { + title: 'Label', + text: 'The display name or label for the service.', + attachTo: {element: '.tutorial-service-label', on: 'top'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-active-checkbox', + type: 'click', + options: { + title: 'The \'active\' checkbox', + text: 'You can make your service inactive when you need.', + attachTo: {element: '.tutorial-step-active-service-checkbox', on: 'bottom'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-config-tab', + type: 'click', + options: { + title: 'Config tab', + text: 'Let\'s open config tab.', + attachTo: {element: '#config-tab', on: 'bottom'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + } + ] + + }, + customFunctionObjects: [ + { + event: 'show', + handler: + function () { + $('#config-tab').on('click', allScenarios.createService.tour.next); + } + }, + { + event: 'hide', + handler: + function () { + $('#config-tab').unbind("click", allScenarios.createService.tour.next); + } + } + ] + }, + + { + name: 'service-host-input', + type: 'input', + options: { + title: 'Host', + text: 'The name of the database host, i.e. localhost, 192.168.1.1, etc.', + attachTo: {element: '.tutorial-step-host-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + $("#info-tab").trigger("click"); + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-port-input', + type: 'input', + options: { + title: 'Port Number', + text: 'The number of the database host port, i.e. 27017', + attachTo: {element: '.tutorial-step-port', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-database-input', + type: 'input', + options: { + title: 'Database', + text: 'The name of the database to connect to on the given server.', + attachTo: {element: '.tutorial-step-database-input', on: 'top'}, + scrollTo: true, + scrollToHandler: function () { + document.getElementById('scroll-element').scrollTop = 350; + }, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-username-input', + type: 'input', + options: { + title: 'Username', + text: 'The name of the database user.', + attachTo: {element: '.tutorial-step-username-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-user-password-input', + type: 'input', + options: { + title: 'User password', + text: 'Type password and click next.', + attachTo: {element: '.tutorial-step-password-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-schema-input', + type: 'input', + options: { + title: 'Schema', + text: '

Leave blank to work with all available schemas, type "default"

' + + '

to only work with the default schema for the given credentials,

' + + '

or type in a specific schema to use for this service.

', + attachTo: {element: '.tutorial-step-schema-input', on: 'top'}, + scrollTo: true, + scrollToHandler: function () { + document.getElementById('scroll-element').scrollTop = 600; + }, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-character-set-input', + type: 'input', + options: { + title: 'Character Set', + text: 'The character set to use for this connection, i.e. utf8.', + attachTo: {element: '.tutorial-step-charset-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-character-set-collation-input', + type: 'input', + options: { + title: 'Character Set Collation ', + text: 'The character set collation to use for this connection, i.e. utf8_unicode_ci.', + attachTo: {element: '.tutorial-step-collation-input', on: 'top'}, + scrollTo: true, + scrollToHandler: function () { + document.getElementById('scroll-element').scrollTop = 700; + }, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + }, + { + text: 'next', + action: function () { + allScenarios.createService.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-save-button', + type: 'input', + options: { + title: 'Save the new service', + text: 'Click save.', + attachTo: {element: '#services_details_save ', on: 'top'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + allScenarios.createService.tour.complete() + } + }, + + { + text: 'back', + action: function () { + allScenarios.createService.tour.back() + } + + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'show-created-service', + type: 'click', + options: { + title: 'Service which we have created', + text: 'You have just created a service. God job :)', + attachTo: {element: '.tutorial-step-created-service', on: 'top'}, + scrollTo: true, + buttons: [ + + { + text: 'DONE', + action: function () { + allScenarios.createService.tour.complete() + } + } + ] + + }, + customFunctionObjects: [ + { + event: 'before-show', + handler: + function () { + angular.element('body').removeClass('shepherd-active'); + document.getElementById('services-table').lastElementChild.lastElementChild.classList.add('tutorial-step-created-service') + } + } + ] + } + ] + } +}; \ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/app-tutorial.html b/dist/admin_components/adf-tutorial/views/app-tutorial.html deleted file mode 100644 index f6705001..00000000 --- a/dist/admin_components/adf-tutorial/views/app-tutorial.html +++ /dev/null @@ -1 +0,0 @@ -

Will be soon :) \ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/main-tutorial.html b/dist/admin_components/adf-tutorial/views/main-tutorial.html index 4cf256f4..c99ca886 100644 --- a/dist/admin_components/adf-tutorial/views/main-tutorial.html +++ b/dist/admin_components/adf-tutorial/views/main-tutorial.html @@ -1 +1 @@ -

\ No newline at end of file +
\ No newline at end of file diff --git a/dist/index.html b/dist/index.html index 69901a0e..22678cd5 100644 --- a/dist/index.html +++ b/dist/index.html @@ -2,7 +2,7 @@

You are using an outdated browser. Please upgrade your browser to improve your experience.

- + diff --git a/app/scripts/tour_scenarios/all.js b/app/scripts/tour_scenarios/all.js deleted file mode 100644 index 98ab4b3e..00000000 --- a/app/scripts/tour_scenarios/all.js +++ /dev/null @@ -1,610 +0,0 @@ -var allScenarios = { - createService: { - steps: [ - { - name: 'services-tab', - type: 'click', - options: { - title: 'Services Tab', - text: 'Tab with settings related to services. Let\'s open it.', - attachTo: {element: '.tutorial-step-services-tab', on: 'bottom'}, - advanceOn: {element: '.tutorial-step-services-tab', on: 'click'}, - buttons: [ - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - } - ] - }, - customFunctionObjects: [] - }, - - { - name: 'create-button', - type: 'click', - options: { - title: 'Button to create a service', - text: 'Let\'s create a service. Click on the button.', - attachTo: {element: '.tutorial-step-create-service-button', on: 'bottom'}, - buttons: [ - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - } - ] - }, - customFunctionObjects: [ - { - event: 'show', - handler: - function () { - $('.tutorial-step-create-service-button').on('click', function (event) { - allScenarios.createService.tour.next() - }); - } - } - ] - }, - - { - name: 'selecting-service-type', - type: 'click', - options: { - title: 'Service type', - text: 'Select \'Database\' service type and choose MySQL', - attachTo: {element: '.tutorial-step-selecting-service-type-dropdown', on: 'top'}, - buttons: [ - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - } - ] - }, - customFunctionObjects: [ - { - event: 'show', - handler: - function () { - angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); - - $('.tutorial-step-service-type-selected').on('click', function (event) { - if ($('.tutorial-step-selecting-service-type-dropdown').text().indexOf('MySQL') !== -1) { - allScenarios.createService.tour.next() - } - }); - } - }, - { - event: 'before-hide', - handler: function () { - angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', 'auto;'); - } - - - } - ] - }, - - { - name: 'service-name-input', - type: 'input', - options: { - title: 'Service name', - text: 'Select a name for making API requests, such as \'db\' in /api/v2/db.', - attachTo: {element: '.tutorial-service-name', on: 'top'}, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - { - text: 'next', - action: function () { - if ($('.tutorial-service-name').val() !== '') { - allScenarios.createService.tour.next() - } - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-label-input', - type: 'input', - options: { - title: 'Label', - text: 'The display name or label for the service.', - attachTo: {element: '.tutorial-service-label', on: 'top'}, - scrollTo: true, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-active-checkbox', - type: 'click', - options: { - title: 'The \'active\' checkbox', - text: 'You can make your service inactive when you need.', - attachTo: {element: '.tutorial-step-active-service-checkbox', on: 'bottom'}, - scrollTo: true, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-config-tab', - type: 'click', - options: { - title: 'Config tab', - text: 'Let\'s open config tab.', - attachTo: {element: '#config-tab', on: 'bottom'}, - scrollTo: true, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - } - ] - - }, - customFunctionObjects: [ - { - event: 'show', - handler: - function () { - $('#config-tab').on('click', allScenarios.createService.tour.next); - } - }, - { - event: 'hide', - handler: - function () { - $('#config-tab').unbind("click", allScenarios.createService.tour.next); - } - } - ] - }, - - { - name: 'service-host-input', - type: 'input', - options: { - title: 'Host', - text: 'The name of the database host, i.e. localhost, 192.168.1.1, etc.', - attachTo: {element: '.tutorial-step-host-input', on: 'top'}, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - $("#info-tab").trigger("click"); - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-port-input', - type: 'input', - options: { - title: 'Port Number', - text: 'The number of the database host port, i.e. 27017', - attachTo: {element: '.tutorial-step-port', on: 'top'}, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-database-input', - type: 'input', - options: { - title: 'Database', - text: 'The name of the database to connect to on the given server.', - attachTo: {element: '.tutorial-step-database-input', on: 'top'}, - scrollTo: true, - scrollToHandler: function () { - document.getElementById('scroll-element').scrollTop = 350; - }, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-username-input', - type: 'input', - options: { - title: 'Username', - text: 'The name of the database user.', - attachTo: {element: '.tutorial-step-username-input', on: 'top'}, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-user-password-input', - type: 'input', - options: { - title: 'User password', - text: 'Type password and click next.', - attachTo: {element: '.tutorial-step-password-input', on: 'top'}, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-schema-input', - type: 'input', - options: { - title: 'Schema', - text: '

Leave blank to work with all available schemas, type "default"

' + - '

to only work with the default schema for the given credentials,

' + - '

or type in a specific schema to use for this service.

', - attachTo: {element: '.tutorial-step-schema-input', on: 'top'}, - scrollTo: true, - scrollToHandler: function () { - document.getElementById('scroll-element').scrollTop = 600; - }, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-character-set-input', - type: 'input', - options: { - title: 'Character Set', - text: 'The character set to use for this connection, i.e. utf8.', - attachTo: {element: '.tutorial-step-charset-input', on: 'top'}, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-character-set-collation-input', - type: 'input', - options: { - title: 'Character Set Collation ', - text: 'The character set collation to use for this connection, i.e. utf8_unicode_ci.', - attachTo: {element: '.tutorial-step-collation-input', on: 'top'}, - scrollTo: true, - scrollToHandler: function () { - document.getElementById('scroll-element').scrollTop = 700; - }, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - }, - { - text: 'next', - action: function () { - allScenarios.createService.tour.next() - } - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'service-save-button', - type: 'input', - options: { - title: 'Save the new service', - text: 'Click save.', - attachTo: {element: '#services_details_save ', on: 'top'}, - scrollTo: true, - buttons: [ - - { - text: 'skip', - classes: 'shepherd-button-secondary', - action: function () { - allScenarios.createService.tour.complete() - } - }, - - { - text: 'back', - action: function () { - allScenarios.createService.tour.back() - } - - } - ] - - }, - customFunctionObjects: [] - }, - - { - name: 'show-created-service', - type: 'click', - options: { - title: 'Service which we have created', - text: 'You have just created a service. God job :)', - attachTo: {element: '.tutorial-step-created-service', on: 'top'}, - scrollTo: true, - buttons: [ - - { - text: 'DONE', - action: function () { - allScenarios.createService.tour.complete() - } - } - ] - - }, - customFunctionObjects: [ - { - event: 'before-show', - handler: - function () { - angular.element('body').removeClass('shepherd-active'); - document.getElementById('services-table').lastElementChild.lastElementChild.classList.add('tutorial-step-created-service') - } - } - ] - } - ] - } -}; \ No newline at end of file diff --git a/app/scripts/tour_scenarios/create_service.scenario.js b/app/scripts/tour_scenarios/create_service.scenario.js new file mode 100644 index 00000000..9fdac247 --- /dev/null +++ b/app/scripts/tour_scenarios/create_service.scenario.js @@ -0,0 +1,608 @@ +var createServiceScenario = { + steps: [ + { + name: 'services-tab', + type: 'click', + options: { + title: 'Services Tab', + text: 'Tab with settings related to services. Let\'s open it.', + attachTo: {element: '.tutorial-step-services-tab', on: 'bottom'}, + advanceOn: {element: '.tutorial-step-services-tab', on: 'click'}, + buttons: [ + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + } + ] + }, + customFunctionObjects: [] + }, + + { + name: 'create-button', + type: 'click', + options: { + title: 'Button to create a service', + text: 'Let\'s create a service. Click on the button.', + attachTo: {element: '.tutorial-step-create-service-button', on: 'bottom'}, + buttons: [ + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + } + ] + }, + customFunctionObjects: [ + { + event: 'show', + handler: + function () { + $('.tutorial-step-create-service-button').on('click', function (event) { + createServiceScenario.tour.next() + }); + } + } + ] + }, + + { + name: 'selecting-service-type', + type: 'click', + options: { + title: 'Service type', + text: 'Select \'Database\' service type and choose MySQL', + attachTo: {element: '.tutorial-step-selecting-service-type-dropdown', on: 'top'}, + buttons: [ + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + } + ] + }, + customFunctionObjects: [ + { + event: 'show', + handler: + function () { + angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); + + $('.tutorial-step-service-type-selected').on('click', function (event) { + if ($('.tutorial-step-selecting-service-type-dropdown').text().indexOf('MySQL') !== -1) { + createServiceScenario.tour.next() + } + }); + } + }, + { + event: 'before-hide', + handler: function () { + angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', 'auto;'); + } + + + } + ] + }, + + { + name: 'service-name-input', + type: 'input', + options: { + title: 'Service name', + text: 'Select a name for making API requests, such as \'db\' in /api/v2/db.', + attachTo: {element: '.tutorial-service-name', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + { + text: 'next', + action: function () { + if ($('.tutorial-service-name').val() !== '') { + createServiceScenario.tour.next() + } + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-label-input', + type: 'input', + options: { + title: 'Label', + text: 'The display name or label for the service.', + attachTo: {element: '.tutorial-service-label', on: 'top'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-active-checkbox', + type: 'click', + options: { + title: 'The \'active\' checkbox', + text: 'You can make your service inactive when you need.', + attachTo: {element: '.tutorial-step-active-service-checkbox', on: 'bottom'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-config-tab', + type: 'click', + options: { + title: 'Config tab', + text: 'Let\'s open config tab.', + attachTo: {element: '#config-tab', on: 'bottom'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + } + ] + + }, + customFunctionObjects: [ + { + event: 'show', + handler: + function () { + $('#config-tab').on('click', createServiceScenario.tour.next); + } + }, + { + event: 'hide', + handler: + function () { + $('#config-tab').unbind("click", createServiceScenario.tour.next); + } + } + ] + }, + + { + name: 'service-host-input', + type: 'input', + options: { + title: 'Host', + text: 'The name of the database host, i.e. localhost, 192.168.1.1, etc.', + attachTo: {element: '.tutorial-step-host-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + $("#info-tab").trigger("click"); + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-port-input', + type: 'input', + options: { + title: 'Port Number', + text: 'The number of the database host port, i.e. 27017', + attachTo: {element: '.tutorial-step-port', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-database-input', + type: 'input', + options: { + title: 'Database', + text: 'The name of the database to connect to on the given server.', + attachTo: {element: '.tutorial-step-database-input', on: 'top'}, + scrollTo: true, + scrollToHandler: function () { + document.getElementById('scroll-element').scrollTop = 350; + }, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-username-input', + type: 'input', + options: { + title: 'Username', + text: 'The name of the database user.', + attachTo: {element: '.tutorial-step-username-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-user-password-input', + type: 'input', + options: { + title: 'User password', + text: 'Type password and click next.', + attachTo: {element: '.tutorial-step-password-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-schema-input', + type: 'input', + options: { + title: 'Schema', + text: '

Leave blank to work with all available schemas, type "default"

' + + '

to only work with the default schema for the given credentials,

' + + '

or type in a specific schema to use for this service.

', + attachTo: {element: '.tutorial-step-schema-input', on: 'top'}, + scrollTo: true, + scrollToHandler: function () { + document.getElementById('scroll-element').scrollTop = 600; + }, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-character-set-input', + type: 'input', + options: { + title: 'Character Set', + text: 'The character set to use for this connection, i.e. utf8.', + attachTo: {element: '.tutorial-step-charset-input', on: 'top'}, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-character-set-collation-input', + type: 'input', + options: { + title: 'Character Set Collation ', + text: 'The character set collation to use for this connection, i.e. utf8_unicode_ci.', + attachTo: {element: '.tutorial-step-collation-input', on: 'top'}, + scrollTo: true, + scrollToHandler: function () { + document.getElementById('scroll-element').scrollTop = 700; + }, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + }, + { + text: 'next', + action: function () { + createServiceScenario.tour.next() + } + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'service-save-button', + type: 'input', + options: { + title: 'Save the new service', + text: 'Click save.', + attachTo: {element: '#services_details_save ', on: 'top'}, + scrollTo: true, + buttons: [ + + { + text: 'skip', + classes: 'shepherd-button-secondary', + action: function () { + createServiceScenario.tour.complete() + } + }, + + { + text: 'back', + action: function () { + createServiceScenario.tour.back() + } + + } + ] + + }, + customFunctionObjects: [] + }, + + { + name: 'show-created-service', + type: 'click', + options: { + title: 'Service which we have created', + text: 'You have just created a service. God job :)', + attachTo: {element: '.tutorial-step-created-service', on: 'top'}, + scrollTo: true, + buttons: [ + + { + text: 'DONE', + action: function () { + createServiceScenario.tour.complete() + } + } + ] + + }, + customFunctionObjects: [ + { + event: 'before-show', + handler: + function () { + angular.element('body').removeClass('shepherd-active'); + document.getElementById('services-table').lastElementChild.lastElementChild.classList.add('tutorial-step-created-service') + } + } + ] + } + ] +}; \ No newline at end of file From ef971e1935cf1d83cb85572c4ba0550ff520484c Mon Sep 17 00:00:00 2001 From: Volodymyr Tymtsiv Date: Mon, 24 Sep 2018 18:07:54 +0300 Subject: [PATCH 14/27] Extract logic to tour_builder. Remove dfServiceDirective. --- .../adf-services/dreamfactory-services.js | 4 +- .../adf-tutorial}/popper.min.js | 0 .../service-tutorial.directive.js | 28 ----- .../adf-tutorial}/shepherd-theme-arrows.css | 0 .../adf-tutorial}/shepherd.min.js | 0 .../adf-tutorial/tutorial.controller.js | 5 + .../adf-tutorial/views/main-tutorial.html | 17 ++- .../adf-tutorial/views/service-tutorial.html | 9 -- app/index.html | 11 +- app/scripts/app.js | 3 +- .../tour_scenarios/create_service.scenario.js | 62 +++++----- app/scripts/tour_scenarios/tour_builder.js | 116 ++++++++++++++++++ app/services/services.module.js | 3 - app/services/tutorial.service.js | 101 --------------- 14 files changed, 173 insertions(+), 186 deletions(-) rename app/{ => admin_components/adf-tutorial}/popper.min.js (100%) delete mode 100644 app/admin_components/adf-tutorial/service-tutorial.directive.js rename app/{ => admin_components/adf-tutorial}/shepherd-theme-arrows.css (100%) rename app/{ => admin_components/adf-tutorial}/shepherd.min.js (100%) delete mode 100644 app/admin_components/adf-tutorial/views/service-tutorial.html create mode 100644 app/scripts/tour_scenarios/tour_builder.js delete mode 100644 app/services/services.module.js delete mode 100644 app/services/tutorial.service.js diff --git a/app/admin_components/adf-services/dreamfactory-services.js b/app/admin_components/adf-services/dreamfactory-services.js index f76c5e48..26ea3241 100644 --- a/app/admin_components/adf-services/dreamfactory-services.js +++ b/app/admin_components/adf-services/dreamfactory-services.js @@ -22,7 +22,7 @@ angular.module('dfServices', ['ngRoute', 'dfUtility']) }]) - .controller('ServicesCtrl', ['$rootScope','dfTutorial', '$scope', 'dfApplicationData', 'dfNotify', '$location', function ($rootScope, dfTutorial, $scope, dfApplicationData, dfNotify, $location) { + .controller('ServicesCtrl', ['$rootScope', '$scope', 'dfApplicationData', 'dfNotify', '$location', function ($rootScope, $scope, dfApplicationData, dfNotify, $location) { $scope.$parent.title = 'Services'; @@ -98,7 +98,7 @@ angular.module('dfServices', ['ngRoute', 'dfUtility']) $scope.loadTabData(true); $scope.showTutorialStep = function (currentStepId, nextStepId) { - dfTutorial.showStepAfterViewInit(currentStepId, nextStepId); + TourBuilder.showStepAfterViewInit(currentStepId, nextStepId); } }]) diff --git a/app/popper.min.js b/app/admin_components/adf-tutorial/popper.min.js similarity index 100% rename from app/popper.min.js rename to app/admin_components/adf-tutorial/popper.min.js diff --git a/app/admin_components/adf-tutorial/service-tutorial.directive.js b/app/admin_components/adf-tutorial/service-tutorial.directive.js deleted file mode 100644 index 46319850..00000000 --- a/app/admin_components/adf-tutorial/service-tutorial.directive.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -angular.module('dfTutorial') - - .directive('dfServiceTutorial', ['MOD_TUTORIALS_ASSET_PATH', 'dfTutorial', function (MOD_TUTORIALS_ASSET_PATH, dfTutorial) { - - return { - restrict: 'E', - templateUrl: MOD_TUTORIALS_ASSET_PATH + 'views/service-tutorial.html', - link: function (scope, elem, attrs) { - - - scope.start = function () { - - var tour = new Shepherd.Tour({ - defaultStepOptions: { - classes: 'shepherd-theme-arrows', - scrollTo: true - } - }); - - dfTutorial.fillWithScenario(tour, createServiceScenario); - - tour.start(); - }; - } - }; - }]); \ No newline at end of file diff --git a/app/shepherd-theme-arrows.css b/app/admin_components/adf-tutorial/shepherd-theme-arrows.css similarity index 100% rename from app/shepherd-theme-arrows.css rename to app/admin_components/adf-tutorial/shepherd-theme-arrows.css diff --git a/app/shepherd.min.js b/app/admin_components/adf-tutorial/shepherd.min.js similarity index 100% rename from app/shepherd.min.js rename to app/admin_components/adf-tutorial/shepherd.min.js diff --git a/app/admin_components/adf-tutorial/tutorial.controller.js b/app/admin_components/adf-tutorial/tutorial.controller.js index 9a368d30..d03d0582 100644 --- a/app/admin_components/adf-tutorial/tutorial.controller.js +++ b/app/admin_components/adf-tutorial/tutorial.controller.js @@ -13,6 +13,11 @@ angular.module('dfTutorial') path: 'service-tutorial' } ]; + + $scope.start = function () { + TourBuilder.buildTour(createServiceScenario); + }; + }]); diff --git a/app/admin_components/adf-tutorial/views/main-tutorial.html b/app/admin_components/adf-tutorial/views/main-tutorial.html index 425baed4..add86a56 100644 --- a/app/admin_components/adf-tutorial/views/main-tutorial.html +++ b/app/admin_components/adf-tutorial/views/main-tutorial.html @@ -2,7 +2,20 @@
-
- +
+ +
+ +
+

Services are where you set up REST API connections to databases, file storage, + email, remote web services, and more. +

+ +
diff --git a/app/admin_components/adf-tutorial/views/service-tutorial.html b/app/admin_components/adf-tutorial/views/service-tutorial.html deleted file mode 100644 index 71ca422e..00000000 --- a/app/admin_components/adf-tutorial/views/service-tutorial.html +++ /dev/null @@ -1,9 +0,0 @@ - - -
-

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more. -

- diff --git a/app/index.html b/app/index.html index 9abf5971..4a5d5188 100644 --- a/app/index.html +++ b/app/index.html @@ -11,7 +11,7 @@ - + @@ -95,8 +95,8 @@ - - + + @@ -122,15 +122,12 @@ - - - - + diff --git a/app/scripts/app.js b/app/scripts/app.js index 37cbf37e..d2790473 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -36,8 +36,7 @@ angular 'dfFileManager', 'dfPackageManager', 'dfLimit', - 'dfTutorial', - 'dfServiceModule' + 'dfTutorial' ]) // each tab uses this in its resolve function to make sure user is allowed access diff --git a/app/scripts/tour_scenarios/create_service.scenario.js b/app/scripts/tour_scenarios/create_service.scenario.js index 9fdac247..f4d80317 100644 --- a/app/scripts/tour_scenarios/create_service.scenario.js +++ b/app/scripts/tour_scenarios/create_service.scenario.js @@ -1,5 +1,6 @@ var createServiceScenario = { steps: [ + { name: 'services-tab', type: 'click', @@ -17,8 +18,7 @@ var createServiceScenario = { } } ] - }, - customFunctionObjects: [] + } }, { @@ -38,7 +38,7 @@ var createServiceScenario = { } ] }, - customFunctionObjects: [ + eventHandlers: [ { event: 'show', handler: @@ -53,7 +53,7 @@ var createServiceScenario = { { name: 'selecting-service-type', - type: 'click', + type: 'select', options: { title: 'Service type', text: 'Select \'Database\' service type and choose MySQL', @@ -68,7 +68,7 @@ var createServiceScenario = { } ] }, - customFunctionObjects: [ + eventHandlers: [ { event: 'show', handler: @@ -119,8 +119,7 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } }, { @@ -155,13 +154,12 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } }, { name: 'service-active-checkbox', - type: 'click', + type: 'notice', options: { title: 'The \'active\' checkbox', text: 'You can make your service inactive when you need.', @@ -191,8 +189,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -222,7 +220,7 @@ var createServiceScenario = { ] }, - customFunctionObjects: [ + eventHandlers: [ { event: 'show', handler: @@ -273,8 +271,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -309,8 +307,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -349,8 +347,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -385,8 +383,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -421,8 +419,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -463,8 +461,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -499,8 +497,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -539,8 +537,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -570,8 +568,8 @@ var createServiceScenario = { } ] - }, - customFunctionObjects: [] + } + }, { @@ -593,7 +591,7 @@ var createServiceScenario = { ] }, - customFunctionObjects: [ + eventHandlers: [ { event: 'before-show', handler: diff --git a/app/scripts/tour_scenarios/tour_builder.js b/app/scripts/tour_scenarios/tour_builder.js new file mode 100644 index 00000000..85547f9b --- /dev/null +++ b/app/scripts/tour_scenarios/tour_builder.js @@ -0,0 +1,116 @@ +var TourBuilder = { + + showStepAfterViewInit: function (currentStepId, stepToBeShown) { + setTimeout(function () { + if (Shepherd.activeTour && Shepherd.activeTour.getCurrentStep().id == currentStepId) { + Shepherd.activeTour.show(stepToBeShown); + } + }, 100) + }, + + buildTour: function (scenario){ + + var tour = new Shepherd.Tour({ + defaultStepOptions: { + classes: 'shepherd-theme-arrows', + scrollTo: true + } + }); + + TourBuilder.fillTourWithScenario(tour, scenario); + + tour.start(); + }, + + fillTourWithScenario: function (tour, scenario) { + scenario.tour = tour; + + scenario.steps + .forEach(function (step) { + + var createdStep = tour.addStep(step.name, step.options); + + TourBuilder.bindEventsByStepType(step, createdStep); + + TourBuilder.bindCustomEvents(step, createdStep); + }); + }, + + bindEventsByStepType: function (step, createdStep) { + switch (step.type) { + case 'click': { + TourBuilder.bindHighlighting(createdStep); + break; + } + case 'input': { + TourBuilder.bindEmptyInputsValidation(createdStep); + TourBuilder.bindFocus(createdStep); + TourBuilder.bindHighlighting(createdStep); + break; + } + case 'select': { + TourBuilder.bindHighlighting(createdStep); + break + } + case 'notice': { + TourBuilder.bindHighlighting(createdStep); + } + } + }, + + bindCustomEvents: function (step, createdStep) { + if (step.eventHandlers !== undefined) { + step.eventHandlers.forEach(function (each) { + createdStep.on(each.event, each.handler); + }) + } + }, + + getSelector: function (step) { + return step.options.attachTo.element; + }, + + bindHighlighting: function (step) { + var selector = TourBuilder.getSelector(step); + + step.on('show', function () { + angular.element(selector).addClass('highlighted-element'); + }); + step.on('before-hide', function () { + angular.element(selector).removeClass('highlighted-element') + }); + }, + + bindEmptyInputsValidation: function (step) { + var inputSelector = TourBuilder.getSelector(step); + var buttonSelector = '.shepherd-element .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button'; + var disabledButtonClass = 'tutorial-disabled-button'; + + step.on('show', function () { + if ($(inputSelector).val() == '') { + $(buttonSelector).addClass(disabledButtonClass); + } + + $(inputSelector).on('input', function (e) { + if ($(inputSelector).val() == '') { + $(buttonSelector).addClass(disabledButtonClass) + } else { + $(buttonSelector).removeClass(disabledButtonClass) + } + }); + + }); + + step.on('before-hide', function () { + $(buttonSelector).removeClass("tutorial-disabled-button") + }); + }, + + bindFocus: function (step) { + var selector = TourBuilder.getSelector(step); + step.on('show', function () { + $(selector).focus(); + }); + } + +} \ No newline at end of file diff --git a/app/services/services.module.js b/app/services/services.module.js deleted file mode 100644 index 7de2950b..00000000 --- a/app/services/services.module.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -angular.module('dfServiceModule', []); \ No newline at end of file diff --git a/app/services/tutorial.service.js b/app/services/tutorial.service.js deleted file mode 100644 index b2d34690..00000000 --- a/app/services/tutorial.service.js +++ /dev/null @@ -1,101 +0,0 @@ -'use strict'; - -angular - .module('dfServiceModule') - .service('dfTutorial', [function () { - - this.showStepAfterViewInit = function (currentStepId, stepToBeShown) { - setTimeout(function () { - if (Shepherd.activeTour && Shepherd.activeTour.getCurrentStep().id == currentStepId) { - Shepherd.activeTour.show(stepToBeShown); - } - }, 100) - }; - - this.fillWithScenario = function (tour, scenario) { - scenario.tour = tour; - - scenario.steps - .forEach(function (step) { - - var createdStep = tour.addStep(step.name, step.options); - - bindEventsByStepType(step, createdStep); - - bindCustomEvents(step, createdStep); - }); - }; - - function bindEventsByStepType(step, createdStep) { - switch (step.type) { - case 'click': { - bindHighlighting(createdStep); - break; - } - case 'input': { - bindEmptyInputsValidation(createdStep); - bindFocus(createdStep); - bindHighlighting(createdStep); - break; - } - case 'select': { - bindHighlighting(createdStep); - } - } - } - - function bindCustomEvents(step, createdStep) { - step.customFunctionObjects.forEach(function (each) { - createdStep.on(each.event, each.handler); - }) - } - - function getSelector(step) { - return step.options.attachTo.element; - } - - function bindHighlighting(step) { - var selector = getSelector(step); - - step.on('show', function () { - angular.element(selector).addClass('highlighted-element'); - }); - step.on('before-hide', function () { - angular.element(selector).removeClass('highlighted-element') - }); - } - - function bindEmptyInputsValidation(step) { - var inputSelector = getSelector(step); - var buttonSelector = '.shepherd-element .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button'; - var disabledButtonClass = 'tutorial-disabled-button'; - - step.on('show', function () { - if ($(inputSelector).val() == '') { - $(buttonSelector).addClass(disabledButtonClass); - } - - $(inputSelector).on('input', function (e) { - if ($(inputSelector).val() == '') { - $(buttonSelector).addClass(disabledButtonClass) - } else { - $(buttonSelector).removeClass(disabledButtonClass) - } - }); - - }); - - step.on('before-hide', function () { - $(buttonSelector).removeClass("tutorial-disabled-button") - }); - } - - function bindFocus(step) { - var selector = getSelector(step); - step.on('show', function () { - $(selector).focus(); - }); - } - - - }]); \ No newline at end of file From 0591ec4cd4d922af85c79d00703e177e309f66ed Mon Sep 17 00:00:00 2001 From: Volodymyr Tymtsiv Date: Tue, 25 Sep 2018 11:54:10 +0300 Subject: [PATCH 15/27] Remove angular usage from create_service scenario. --- app/scripts/tour_scenarios/create_service.scenario.js | 10 ++++------ .../adf-tutorial/views/main-tutorial.html | 2 +- .../adf-tutorial/views/service-tutorial.html | 1 - dist/index.html | 2 +- dist/scripts/app.2ea7f404.js | 1 - dist/scripts/app.38b8a49d.js | 1 + 6 files changed, 7 insertions(+), 10 deletions(-) delete mode 100644 dist/admin_components/adf-tutorial/views/service-tutorial.html delete mode 100644 dist/scripts/app.2ea7f404.js create mode 100644 dist/scripts/app.38b8a49d.js diff --git a/app/scripts/tour_scenarios/create_service.scenario.js b/app/scripts/tour_scenarios/create_service.scenario.js index f4d80317..bd063873 100644 --- a/app/scripts/tour_scenarios/create_service.scenario.js +++ b/app/scripts/tour_scenarios/create_service.scenario.js @@ -73,9 +73,9 @@ var createServiceScenario = { event: 'show', handler: function () { - angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); + $('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); - $('.tutorial-step-service-type-selected').on('click', function (event) { + $('.tutorial-step-service-type-selected').on('click', function () { if ($('.tutorial-step-selecting-service-type-dropdown').text().indexOf('MySQL') !== -1) { createServiceScenario.tour.next() } @@ -85,10 +85,8 @@ var createServiceScenario = { { event: 'before-hide', handler: function () { - angular.element('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', 'auto;'); + $('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', 'auto'); } - - } ] }, @@ -596,7 +594,7 @@ var createServiceScenario = { event: 'before-show', handler: function () { - angular.element('body').removeClass('shepherd-active'); + $('body').removeClass('shepherd-active'); document.getElementById('services-table').lastElementChild.lastElementChild.classList.add('tutorial-step-created-service') } } diff --git a/dist/admin_components/adf-tutorial/views/main-tutorial.html b/dist/admin_components/adf-tutorial/views/main-tutorial.html index c99ca886..485c33fa 100644 --- a/dist/admin_components/adf-tutorial/views/main-tutorial.html +++ b/dist/admin_components/adf-tutorial/views/main-tutorial.html @@ -1 +1 @@ -
\ No newline at end of file +

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more.

\ No newline at end of file diff --git a/dist/admin_components/adf-tutorial/views/service-tutorial.html b/dist/admin_components/adf-tutorial/views/service-tutorial.html deleted file mode 100644 index e89f1841..00000000 --- a/dist/admin_components/adf-tutorial/views/service-tutorial.html +++ /dev/null @@ -1 +0,0 @@ -

Services are where you set up REST API connections to databases, file storage, email, remote web services, and more.

\ No newline at end of file diff --git a/dist/index.html b/dist/index.html index 22678cd5..4eb23d17 100644 --- a/dist/index.html +++ b/dist/index.html @@ -2,7 +2,7 @@

You are using an outdated browser. Please upgrade your browser to improve your experience.

- + @@ -126,8 +124,13 @@ - - + + + + + + + diff --git a/app/admin_components/adf-tutorial/Readme.md b/app/scripts/feature_tour/Readme.md similarity index 95% rename from app/admin_components/adf-tutorial/Readme.md rename to app/scripts/feature_tour/Readme.md index 7b3685bc..33bf3f72 100644 --- a/app/admin_components/adf-tutorial/Readme.md +++ b/app/scripts/feature_tour/Readme.md @@ -2,7 +2,7 @@ To add a new tutorial you need to do the following: -1) Add a file with a scenario to tour_scenarios folder which you want to implement +1) Add a file with a scenario to `scripts/feature_tour/scenarios` folder which you want to implement 2) Create a method in tutorial.controller.js which will start the tour. 3) Create a button in main-tutorial.html. 4) Add ng-click directive to the button with a method which will start the tour. diff --git a/app/scripts/tour_scenarios/tour_builder.js b/app/scripts/feature_tour/feature_tour.js similarity index 67% rename from app/scripts/tour_scenarios/tour_builder.js rename to app/scripts/feature_tour/feature_tour.js index 081fa19f..2f21bb9e 100644 --- a/app/scripts/tour_scenarios/tour_builder.js +++ b/app/scripts/feature_tour/feature_tour.js @@ -1,14 +1,20 @@ -var TourBuilder = { +var FeatureTour = { + current: undefined, + scenarios: {}, - showStepAfterViewInit: function (currentStepId, stepToBeShown) { + //This is a hack to show a step after the corresponding Angular's view was rendered + showStep: function (currentStepId, stepToBeShown) { setTimeout(function () { - if (Shepherd.activeTour && Shepherd.activeTour.getCurrentStep().id == currentStepId) { - Shepherd.activeTour.show(stepToBeShown); + if (FeatureTour.current && FeatureTour.current.getCurrentStep().id == currentStepId) { + FeatureTour.current.show(stepToBeShown); } - }, 100) + }, 100); + + return 'done'; }, - buildTour: function (scenario) { + start: function(scenarioName) { + var scenario = this.scenarios[scenarioName] var tour = new Shepherd.Tour({ defaultStepOptions: { @@ -17,26 +23,26 @@ var TourBuilder = { } }); - TourBuilder.fillTourWithScenario(tour, scenario); + this.current = tour; + + this.fillTourWithScenario(tour, scenario); tour.start(); }, - fillTourWithScenario: function (tour, scenario) { - scenario.tour = tour; + var self = this; scenario.steps - .forEach(function (step) { + .forEach(function (stepTemplate) { - var stepButtons = TourBuilder.createButtons(step, tour); + var buttons = self.createButtons(stepTemplate, tour); - var createdStep = tour.addStep(step.name, step.options); - createdStep.options.buttons = stepButtons; + var step = tour.addStep(stepTemplate.name, stepTemplate.options); + step.options.buttons = buttons; - TourBuilder.bindEventsByStepType(step, createdStep); - - TourBuilder.bindCustomEvents(step, createdStep); + self.bindEventsByStepType(stepTemplate, step); + self.bindCustomEvents(stepTemplate, step); }); }, @@ -53,21 +59,24 @@ var TourBuilder = { button = { text: 'skip', classes: 'shepherd-button-secondary', - action: tour.complete + action: function (){ + FeatureTour.current.complete(); + FeatureTour.current = undefined; + } }; break; } case 'next': { button = { text: 'next', - action: tour.next + action: FeatureTour.current.next }; break; } case 'back': { button = { text: 'back', - action: tour.back + action: FeatureTour.current.back }; break; } @@ -90,21 +99,21 @@ var TourBuilder = { bindEventsByStepType: function (step, createdStep) { switch (step.type) { case 'click': { - TourBuilder.bindHighlighting(createdStep); + this.bindHighlighting(createdStep); break; } case 'input': { - TourBuilder.bindEmptyInputsValidation(createdStep); - TourBuilder.bindFocus(createdStep); - TourBuilder.bindHighlighting(createdStep); + this.bindEmptyInputsValidation(createdStep); + this.bindFocus(createdStep); + this.bindHighlighting(createdStep); break; } case 'select': { - TourBuilder.bindHighlighting(createdStep); + this.bindHighlighting(createdStep); break } case 'notice': { - TourBuilder.bindHighlighting(createdStep); + this.bindHighlighting(createdStep); } } }, @@ -122,7 +131,7 @@ var TourBuilder = { }, bindHighlighting: function (step) { - var selector = TourBuilder.getSelector(step); + var selector = this.getSelector(step); step.on('show', function () { $(selector).addClass('highlighted-element'); @@ -133,7 +142,7 @@ var TourBuilder = { }, bindEmptyInputsValidation: function (step) { - var inputSelector = TourBuilder.getSelector(step); + var inputSelector = this.getSelector(step); var buttonSelector = '.shepherd-element .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button'; var disabledButtonClass = 'tutorial-disabled-button'; @@ -158,10 +167,9 @@ var TourBuilder = { }, bindFocus: function (step) { - var selector = TourBuilder.getSelector(step); + var selector = this.getSelector(step); step.on('show', function () { $(selector).focus(); }); } - -}; \ No newline at end of file +} diff --git a/app/scripts/tour_scenarios/create_service.scenario.js b/app/scripts/feature_tour/scenarios/create_service.scenario.js similarity index 95% rename from app/scripts/tour_scenarios/create_service.scenario.js rename to app/scripts/feature_tour/scenarios/create_service.scenario.js index e144390c..2970ab07 100644 --- a/app/scripts/tour_scenarios/create_service.scenario.js +++ b/app/scripts/feature_tour/scenarios/create_service.scenario.js @@ -1,4 +1,4 @@ -var createServiceScenario = { +FeatureTour.scenarios.createService = { steps: [ { @@ -36,7 +36,7 @@ var createServiceScenario = { handler: function () { $('.tutorial-step-create-service-button').click(function () { - createServiceScenario.tour.next() + FeatureTour.current.next(); }); } } @@ -65,7 +65,7 @@ var createServiceScenario = { $('.tutorial-step-service-type-selected').on('click', function () { if ($('.tutorial-step-selecting-service-type-dropdown').text().indexOf('MySQL') !== -1) { - createServiceScenario.tour.next() + FeatureTour.current.next(); } }); } @@ -95,7 +95,7 @@ var createServiceScenario = { type: 'next', action: function () { if ($('.tutorial-service-name').val() !== '') { - createServiceScenario.tour.next() + FeatureTour.current.next(); } } } @@ -177,14 +177,14 @@ var createServiceScenario = { event: 'show', handler: function () { - $('#config-tab').on('click', createServiceScenario.tour.next); + $('#config-tab').on('click', FeatureTour.current.next); } }, { event: 'hide', handler: function () { - $('#config-tab').unbind("click", createServiceScenario.tour.next); + $('#config-tab').unbind("click", FeatureTour.current.next); } } ] @@ -207,7 +207,7 @@ var createServiceScenario = { type: 'back', action: function () { $("#info-tab").trigger("click"); - createServiceScenario.tour.back() + FeatureTour.current.back() } }, @@ -331,7 +331,7 @@ var createServiceScenario = { options: { title: 'Schema', text: '

Type "default" to only work with the default schema for the given credentials,

' + - '

or type in a specific schema to use for this service.

', + '

or type in a specific schema to use for this service.

', attachTo: {element: '.tutorial-step-schema-input', on: 'top'}, scrollTo: true, scrollToHandler: function () { @@ -460,4 +460,4 @@ var createServiceScenario = { ] } ] -}; \ No newline at end of file +}; diff --git a/app/scripts/feature_tour/scenarios/scripting.scenario.js b/app/scripts/feature_tour/scenarios/scripting.scenario.js new file mode 100644 index 00000000..cc26c348 --- /dev/null +++ b/app/scripts/feature_tour/scenarios/scripting.scenario.js @@ -0,0 +1,259 @@ +FeatureTour.scenarios.scripting = { + steps: [ + { + name: 'scripts-tab', + type: 'click', + options: { + title: 'Scripts Tab', + text: 'Click on this tab to go to the scripts page.', + attachTo: {element: '[data-tutorial=scripting][data-step=scripts-tab]', on: 'bottom'}, + advanceOn: {element: '[data-tutorial=scripting][data-step=scripts-tab]', on: 'click'}, + buttons: [ + { + type: 'skip' + } + ] + } + }, + + { + name: 'choose-system-service', + type: 'click', + options: { + title: 'System Service', + text: 'Select system service', + attachTo: { element: '[data-tutorial=scripting][data-step=select-service-system]', on: 'bottom'}, + advanceOn: { element: '[data-tutorial=scripting][data-step=select-service-system]', on: 'click'}, + buttons: [ + { + type: 'skip' + } + ] + } + }, + + { + name: 'choose-system-admin', + type: 'click', + options: { + title: 'Admin', + text: 'Select system.admin', + attachTo: {element: '[data-tutorial=scripting][data-step=choose-system-admin]', on: 'bottom'}, + buttons: [ + { + type: 'skip' + } + ] + } + }, + + { + name: 'choose-admin-post-process', + type: 'click', + options: { + title: 'Post Process', + text: 'Select system.admin.get.post_process', + attachTo: {element: '[data-tutorial=scripting][data-step=system-admin-get-post_process]', on: 'bottom'}, + buttons: [ + { + type: 'skip' + } + ] + } + }, + + { + name: 'again-choose-admin-post-process', + type: 'click', + options: { + title: 'Post Process', + text: 'Select system.admin.get.post_process again', + attachTo: {element: '[data-tutorial=scripting][data-step=system-admin-get-post_process-again]', on: 'bottom'}, + buttons: [ + { + type: 'skip' + } + ] + }, + eventHandlers: [ + { + event: 'show', + handler: + function () { + $('[data-tutorial=scripting][data-step=system-admin-get-post_process-again]').on('click', function () { + setTimeout(function(){ + FeatureTour.current.next(); + }, 100) + }); + } + } + ] + }, + + { + name: 'choose-language', + type: 'select', + options: { + title: 'Select Language', + text: 'Open the list above and select PHP', + attachTo: {element: '[data-tutorial=scripting][data-step=choose-language]', on: 'bottom'}, + buttons: [ + { + type: 'skip' + } + ] + }, + eventHandlers: [ + { + event: 'show', + handler: + function () { + var $select = $('[data-tutorial=scripting][data-step=choose-language]'); + $select.on('change', function (e) { + if ($select.find('option').filter(':selected').val() === "string:php") { + FeatureTour.current.next(); + } + }); + } + } + ] + }, + + { + name: 'activate-script', + type: 'click', + options: { + title: 'Activate Script', + text: 'Check the checkbox to make a script active. You can later turn it off by unchecking this checkbox.', + attachTo: {element: '[data-tour=scripting][data-step=activate-script]', on: 'bottom'}, + advanceOn: {element: '[data-tour=scripting][data-step=activate-script]', on: 'click'}, + buttons: [ + { + type: 'skip' + } + ] + }, + eventHandlers: [ + { + event: 'show', + handler: + function () { + // $('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); + var $checkbox = $('[data-tour=scripting][data-step=activate-script]'); + $checkbox.on('change', function (e) { + if ($checkbox.is(":checked")) { + FeatureTour.current.next(); + } + }); + } + } + ] + }, + + { + name: 'modify-response', + type: 'click', + options: { + title: 'Modify Response', + text: 'Check this checkbox to allow the modification of response which will then be available for using in script.', + attachTo: {element: '[data-tour=scripting][data-step=modify-response]', on: 'bottom'}, + // advanceOn: {element: '.tutorial-step-select-service-system', on: 'click'}, + buttons: [ + { + type: 'skip' + } + ] + }, + eventHandlers: [ + { + event: 'show', + handler: + function () { + // $('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); + var $checkbox = $('[data-tour=scripting][data-step=modify-response]'); + $checkbox.on('change', function (e) { + if ($checkbox.is(":checked")) { + FeatureTour.current.next(); + } + }); + } + } + ] + }, + + { + name: 'show-script-editor', + type: 'notice', + options: { + title: 'Script Editor', + text: "Notice the editor area. This is a place where you can write your custom scripts.
This time we will do it for you. So after you click next we will automatically fill in the example script.", + attachTo: {element: '[data-tour=scripting][data-step-1=show-script-editor]', on: 'top'}, + // advanceOn: {element: '.tutorial-step-select-service-system', on: 'click'}, + buttons: [ + { + type: 'skip' + }, + { + type: 'next' + } + ] + } + }, + + { + name: 'fill-in-example-script', + type: 'notice', + options: { + title: 'Example Script', + text: "Notice that we just inserted an example script.
It simply operates with response object by adding a custom field.", + attachTo: {element: '[data-tour=scripting][data-step-2=fill-in-script]', on: 'top'}, + buttons: [ + { + type: 'skip' + }, + { + type: 'next' + } + ] + }, + eventHandlers: [ + { + event: 'show', + handler: + function () { + var $scope = angular.element($('.scripts-page')[0]).scope().$parent; + $scope.$apply(function(x){x.currentScriptObj.content = "$responseBody = $event['response']['content'];\n\n$responseBody['my_custom_field'] = [\n 'content' => [\n 'success' => true,\n 'message' => \"This is just an example message.\"\n ]\n ];\n \n$event['response']['content'] = $responseBody;\n"}); + } + } + ] + }, + + { + name: 'save-example-script', + type: 'click', + options: { + title: 'Save Script', + text: "Now it is time to save the script.
After saving the script you can go to API docs to try it and see that custom field is present in the response.", + attachTo: {element: '[data-tour=scripting][data-step=save-example-script]', on: 'bottom'}, + buttons: [ + { + type: 'skip' + } + ] + } + , + eventHandlers: [ + { + event: 'show', + handler: + function () { + $('[data-tour=scripting][data-step=save-example-script]').on('click', function () { + FeatureTour.current.complete(); + }) + } + } + ] + } + + ] +} diff --git a/app/styles/sass/partials/_df-tutorial.scss b/app/styles/sass/partials/_df-tutorial.scss index bc3a09bf..c9df5e2e 100644 --- a/app/styles/sass/partials/_df-tutorial.scss +++ b/app/styles/sass/partials/_df-tutorial.scss @@ -1,6 +1,6 @@ .highlighted-element { position: relative; - z-index: 1102; + z-index: 1102!important; background-color: white; border: 1px solid rgba(0, 0, 0, 0.4); border-radius: 6px; diff --git a/app/styles/sass/styles.css b/app/styles/sass/styles.css index 1488cc4f..6081c626 100644 --- a/app/styles/sass/styles.css +++ b/app/styles/sass/styles.css @@ -9571,7 +9571,7 @@ body { /* line 1, partials/_df-tutorial.scss */ .highlighted-element { position: relative; - z-index: 1102; + z-index: 1102!important; background-color: white; border: 1px solid rgba(0, 0, 0, 0.4); border-radius: 6px; From 9293642a07ec4ad3f46c20098a6b60f48ab79e9f Mon Sep 17 00:00:00 2001 From: OlegL Date: Fri, 28 Sep 2018 15:23:56 +0300 Subject: [PATCH 25/27] #107 Fix first step of database service tutorial --- app/scripts/feature_tour/scenarios/create_service.scenario.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/scripts/feature_tour/scenarios/create_service.scenario.js b/app/scripts/feature_tour/scenarios/create_service.scenario.js index 2970ab07..4eb1a8a3 100644 --- a/app/scripts/feature_tour/scenarios/create_service.scenario.js +++ b/app/scripts/feature_tour/scenarios/create_service.scenario.js @@ -7,8 +7,8 @@ FeatureTour.scenarios.createService = { options: { title: 'Services Tab', text: 'Click on this tab to go to the services page.', - attachTo: {element: '.tutorial-step-services-tab', on: 'bottom'}, - advanceOn: {element: '.tutorial-step-services-tab', on: 'click'}, + attachTo: {element: '[data-step=services-tab]', on: 'bottom'}, + advanceOn: {element: '[data-step=services-tab]', on: 'click'}, buttons: [ { type: 'skip' From c3705f03a9352ef09aeb53e330c607e6ba92120c Mon Sep 17 00:00:00 2001 From: OlegL Date: Fri, 28 Sep 2018 15:50:37 +0300 Subject: [PATCH 26/27] #107 Minor text improvement --- app/scripts/feature_tour/scenarios/create_service.scenario.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/feature_tour/scenarios/create_service.scenario.js b/app/scripts/feature_tour/scenarios/create_service.scenario.js index 4eb1a8a3..f9cd50ad 100644 --- a/app/scripts/feature_tour/scenarios/create_service.scenario.js +++ b/app/scripts/feature_tour/scenarios/create_service.scenario.js @@ -225,7 +225,7 @@ FeatureTour.scenarios.createService = { type: 'input', options: { title: 'Port Number', - text: 'Enter the number of the port where database is running, i.e. 3306 which is default for MySql', + text: 'Enter the number of the port where database is running, i.e. 3306 which is default for MySQL', attachTo: {element: '.tutorial-step-port', on: 'top'}, buttons: [ From 51f11fddb6e9fff8604b7359121bfea14a81ad7e Mon Sep 17 00:00:00 2001 From: OlegL Date: Fri, 28 Sep 2018 17:03:17 +0300 Subject: [PATCH 27/27] #107 Remove comments --- app/scripts/feature_tour/scenarios/scripting.scenario.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/scripts/feature_tour/scenarios/scripting.scenario.js b/app/scripts/feature_tour/scenarios/scripting.scenario.js index cc26c348..4d4754e1 100644 --- a/app/scripts/feature_tour/scenarios/scripting.scenario.js +++ b/app/scripts/feature_tour/scenarios/scripting.scenario.js @@ -138,7 +138,6 @@ FeatureTour.scenarios.scripting = { event: 'show', handler: function () { - // $('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); var $checkbox = $('[data-tour=scripting][data-step=activate-script]'); $checkbox.on('change', function (e) { if ($checkbox.is(":checked")) { @@ -157,7 +156,6 @@ FeatureTour.scenarios.scripting = { title: 'Modify Response', text: 'Check this checkbox to allow the modification of response which will then be available for using in script.', attachTo: {element: '[data-tour=scripting][data-step=modify-response]', on: 'bottom'}, - // advanceOn: {element: '.tutorial-step-select-service-system', on: 'click'}, buttons: [ { type: 'skip' @@ -169,7 +167,6 @@ FeatureTour.scenarios.scripting = { event: 'show', handler: function () { - // $('.tutorial-step-selecting-service-type-dropdown-list').css('z-index', '1102'); var $checkbox = $('[data-tour=scripting][data-step=modify-response]'); $checkbox.on('change', function (e) { if ($checkbox.is(":checked")) { @@ -188,7 +185,6 @@ FeatureTour.scenarios.scripting = { title: 'Script Editor', text: "Notice the editor area. This is a place where you can write your custom scripts.
This time we will do it for you. So after you click next we will automatically fill in the example script.", attachTo: {element: '[data-tour=scripting][data-step-1=show-script-editor]', on: 'top'}, - // advanceOn: {element: '.tutorial-step-select-service-system', on: 'click'}, buttons: [ { type: 'skip'