1
0
Fork 0
mirror of https://github.com/mmumshad/ansible-playable.git synced 2025-02-12 19:41:52 +00:00

Merge pull request #5 from mmumshad/bugfix-ui-fixes

Bugfix ui fixes
This commit is contained in:
Mumshad Mannambeth 2017-07-20 17:36:22 -04:00 committed by GitHub
commit bd5384ddb3
10 changed files with 383 additions and 368 deletions

View file

@ -81,7 +81,7 @@ import SearchRoleController from './designer/roles/search_role/search_role.contr
import ComplexVarModalController from './modals/complex_var_modal/complex_var_modal.controller';
import VideoController from './modals/video/video.controller';
import NewModuleController from './custom_modules/new_module/new_module.controller';
import NewModuleComponent from './custom_modules/new_module/new_module.component';
import dictToKeyValueArray from './filters/dictToKeyValueArray/dictToKeyValueArray.filter';
import dictToKeyValueArraySimple from './filters/dictToKeyValueArraySimple/dictToKeyValueArraySimple.filter';
@ -102,12 +102,12 @@ import './app.css';
angular.module('app2App', [ngCookies, ngResource, ngSanitize, uiRouter, uiBootstrap, _Auth, account,
admin, 'validation.match', 'ui.ace', navbar, footer, main, constants, util, ansi2html, ngAnimate, 'angular-confirm',
// Components
DesignerComponent, ProjectComponent, InventoryComponent, PlaybookComponent, FileBrowserComponent, RolesComponent, RunsComponent, CustomModulesComponent,
DesignerComponent, ProjectComponent, InventoryComponent, PlaybookComponent, FileBrowserComponent, RolesComponent, RunsComponent, CustomModulesComponent, NewModuleComponent,
// Services
YAML, yamlFile, Projects, ansible, ansi2html, editor, customModules, system,
// Controllers
NewInventoryController, NewGroupController, NewHostController, ComplexVarController, NewPlaybookController, ExecutionController, NewPlayController, NewTaskController, ComplexVarModalController,
NewFileController, NewRoleController, SearchRoleController, NewModuleController, VideoController,
NewFileController, NewRoleController, SearchRoleController, VideoController,
// Filters
dictToKeyValueArray, dictToKeyValueArraySimple, keyValueArrayToDict, keyValueArrayToArray, addDotInKey, removeDotInKey, json2yaml,
// Directives

View file

@ -3,6 +3,8 @@ const angular = require('angular');
const uiRouter = require('angular-ui-router');
//@require "./**/*.html"
import routes from './custom_modules.routes';
export class CustomModulesComponent {
@ -101,6 +103,10 @@ export class CustomModulesComponent {
}
});
//To fix a warning message in console
customModulesCtrl.aceLoaded = function(_editor){
_editor.$blockScrolling = Infinity;
};
/**
* On Code Change

View file

@ -37,16 +37,17 @@
</div>
</div>
<div ng-show="customModulesCtrl.showNewModuleForm.value" ng-include="'/app/custom_modules/new_module/new_module.html'"></div>
<!--<div ng-show="customModulesCtrl.showNewModuleForm.value" ng-include="'new_module.html'"></div>-->
<div ng-show="customModulesCtrl.showNewModuleForm.value" >
<new-module>
</new-module>
<!--<new-module>
</new-module>-->
<new-module></new-module>
</div>
</div>
<div class="col-md-5">
<div ng-readonly="!customModulesCtrl.showNewModuleForm.value" ui-ace="{theme:'twilight',document:'Python',mode:'python',onChange:customModulesCtrl.codeChanged}" ng-model="customModulesCtrl.selectedModule.module_code">
<div ng-readonly="!customModulesCtrl.showNewModuleForm.value" ui-ace="{theme:'twilight',document:'Python',mode:'python',onChange:customModulesCtrl.codeChanged,onLoad:customModulesCtrl.aceLoaded}" ng-model="customModulesCtrl.selectedModule.module_code">
</div>

View file

@ -0,0 +1,333 @@
'use strict';
const angular = require('angular');
export class newModuleComponent {
/*@ngInject*/
constructor($scope,$filter,customModules,ansible,YAML) {
'ngInject';
var newModuleCtrl = this;
// List of options types for module parameters to be displayed in UI
newModuleCtrl.optionTypes = ['str','list','dict','bool','int','float','path','raw','jsonarg','json','bytes','bits'];
var parentCtrl = $scope.$parent.customModulesCtrl;
// Define the default module object
var defaultModule = {
module:null,
short_description:"",
description:"",
version_added:"",
author:"",
notes: "",
requirements: "",
options:[
{
name:"parameter1",
description: 'Description of parameter 1',
required: true,
default: null,
choices: '"choice1", "choice2"',
aliases: '"option1", "argument1"',
type: ""
}
]
};
// Load Default Template
newModuleCtrl.loadDefaultTemplate = function(){
newModuleCtrl.newModule = angular.copy(defaultModule);
parentCtrl.selectedModule.module_code = "Loading Template..";
customModules.show('template.py',function(response) {
parentCtrl.selectedModule.module_code = response.data.split("Stream :: close")[0];
});
};
// Watch for change in new module and update Documentation, parameters and examples dynamically
$scope.$watch('$ctrl.newModule',function(newValue,oldValue){
if(!newValue)return;
updateDocumentation(newValue);
updateParameters(newValue);
updateExamples(newValue);
},true);
/**
* Update parameters
* Use regex to identify patterns in code and update parameter section dynamically
* */
var updateParameters = function(newValue){
newValue = angular.copy(newValue);
var parameters_definition_lines = [];
var parameters_retreive_lines = [];
angular.forEach(newValue.options,function(option){
if(option.name) {
var line = option.name + "=dict(";
var line_arguments = [];
if (option.required)line_arguments.push("required=True");
if (!option.required && option.default)line_arguments.push("default='" + option.default + "'");
if (option.type)line_arguments.push("type='" + option.type + "'");
if (option.choices)line_arguments.push("choices=[" + option.choices + "]");
if (option.aliases)line_arguments.push("aliases=[" + option.aliases + "]");
line += line_arguments.join(",");
line += ")";
parameters_definition_lines.push(line);
parameters_retreive_lines.push(option.name + ' = module.params[\'' + option.name + '\']')
}
});
var parameters_definition_string = parameters_definition_lines.join(",\n ");
var parameters_retreive_string = parameters_retreive_lines.join("\n ");
var re = /(# <--Begin Parameter Definition -->\s+ )([^]+)(\s+ # <--END Parameter Definition -->)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re,"$1" + parameters_definition_string + "$3");
var supports_check_mode_string = '\n';
if(newValue.supports_check_mode){
supports_check_mode_string = '\n , supports_check_mode=True\n'
}
var re2 = /(# <--Begin Supports Check Mode -->)([^]+)( # <--End Supports Check Mode -->)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re2,"$1" + supports_check_mode_string + "$3");
var re3 = /(# <--Begin Retreiving Parameters -->\s+ )([^]+)(\s+ # <--End Retreiving Parameters -->)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re3,"$1" + parameters_retreive_string + "$3");
};
/**
* Update Documentation
* Update documentation section dynamically based on user input
*
* */
var updateDocumentation = function(newValue){
newValue = angular.copy(newValue);
newValue.options = convertOptionsToObject(newValue.options);
delete newValue['supports_check_mode'];
if(newValue.description)
newValue.description = newValue.description.split(";");
if(newValue.notes)
newValue.notes = newValue.notes.split(";");
if(newValue.requirements)
newValue.requirements = newValue.requirements.split(";");
newModuleCtrl.documentation_yaml = '---\n' + $filter('json2yaml')(angular.toJson(newValue)).toString().replace(/__dot__/g,".");
//var re = /(.*DOCUMENTATION = '''\n)([^]+?)(\n'''.*)/;
var re = /([^]+DOCUMENTATION = '''\s+)([^]+?)(\s+'''[^]+)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re,'$1' + newModuleCtrl.documentation_yaml + '$3');
};
var updateExamples = function(newValue){
newValue = angular.copy(newValue);
var moduleCopy = {
};
moduleCopy[newValue.module] = convertOptionsToExampleObject(newValue.options);
newModuleCtrl.example_yaml = YAML.stringify(moduleCopy,4);
//var re = /(.*DOCUMENTATION = '''\n)([^]+?)(\n'''.*)/;
var re = /([^]+EXAMPLES = '''[^]+# <-- -->\s+)([^]+?)(\s+# <-- \/ -->\s+'''[^]+)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re,'$1' + newModuleCtrl.example_yaml + '$3');
};
/**
* Convert Options to Object
* */
var convertOptionsToObject = function(options){
var result = {};
angular.forEach(options,function(option){
if(option.name){
result[option.name] = {
description: option.description
};
if(option.required)
result[option.name]['required'] = "True";
else
delete result[option.name]['required'];
if(!option.required && option.default)
result[option.name]['default'] = option.default;
if(option.choices){
result[option.name]['choices'] = "[" + option.choices + "]"
}
if(option.aliases){
result[option.name]['aliases'] = "[" + option.aliases + "]"
}
}
});
return result
};
/**
* Convert Options to Example Object
* */
var convertOptionsToExampleObject = function(options){
var result = {};
angular.forEach(options,function(option){
if(option.name){
result[option.name] = "value";
}
});
return result
};
/**
* Convert Options to Array
* */
var convertOptionsToArrays = function(options){
var result = [];
angular.forEach(options,function(value,key){
var option = {
name: key,
description: value.description,
required: value.required,
default:value.default
};
if(value.choices && value.choices.length)
option['choices'] = value.choices.map(function(item){return ('"' + item + '"')}).join(",");
if(value.aliases && value.aliases.length)
option['aliases'] = value.aliases.map(function(item){return ('"' + item + '"')}).join(",");
result.push(option)
});
return result
};
/**
* Save New Module
*
* */
newModuleCtrl.saveNewModule = function(){
newModuleCtrl.saving = true;
customModules.save(newModuleCtrl.newModule.module + '.py',parentCtrl.selectedModule.module_code,function(response){
newModuleCtrl.saving = false;
parentCtrl.getCustomModules();
ansible.getAnsibleModules(function(response){
}, function(response){
},null,true);
newModuleCtrl.cancelNewModule();
},function(response){
newModuleCtrl.saving = false;
console.error(response.data)
})
};
/**
* Cancel New Module
*
* */
newModuleCtrl.cancelNewModule = function(){
parentCtrl.showNewModuleForm.value = false;
parentCtrl.showModuleCode(parentCtrl.selectedModule.module.name)
};
/**
* Get properties from code to display in UI
*
* */
var getPropertiesFromCode = function(module_code){
//var re = /([^]+DOCUMENTATION = '''\n)([^]+?)(\n'''[^]+)/;
var re = /([^]+DOCUMENTATION = '''\s+)([^]+?)(\s+'''[^]+)/;
var module_string = parentCtrl.selectedModule.module_code.replace(re,'$2');
newModuleCtrl.newModule = YAML.parse(module_string);
newModuleCtrl.newModule.options = convertOptionsToArrays(newModuleCtrl.newModule.options);
if(newModuleCtrl.newModule.description && newModuleCtrl.newModule.description.length)
newModuleCtrl.newModule.description = newModuleCtrl.newModule.description.join(";");
if(newModuleCtrl.newModule.notes && newModuleCtrl.newModule.notes.length)
newModuleCtrl.newModule.notes = newModuleCtrl.newModule.notes.join(";");
if(newModuleCtrl.newModule.requirements && newModuleCtrl.newModule.requirements.length)
newModuleCtrl.newModule.requirements = newModuleCtrl.newModule.requirements.join(";");
re = /([^]+# <--Begin Parameter Definition -->\s+ )([^]+)(\s+ # <--END Parameter Definition -->[^]+)/;
var parameter_string = parentCtrl.selectedModule.module_code.replace(re,"$2");
// Read property type form parameter definition
re = /\s+(.*?)=.*type=(.*?)[,\)].*/g;
var m;
while ((m = re.exec(parameter_string)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
if(m[1]){
angular.forEach(newModuleCtrl.newModule.options,function(option){
if(option.name === m[1]){
option.type = m[2].replace(/'/g,'')
}
})
}
}
};
$scope.$on('editModule', function(e) {
getPropertiesFromCode(newModuleCtrl.selected_module_code)
});
$scope.$on('newModule', function(e) {
newModuleCtrl.loadDefaultTemplate();
});
}
}
export default angular.module('webAppApp.new_module', [])
.component('newModule', {
template: require('./new_module.html'),
bindings: { message: '<' },
controller: newModuleComponent
})
.name;

View file

@ -0,0 +1,17 @@
'use strict';
describe('Component: newModule', function() {
// load the component's module
beforeEach(module('webAppApp.new_module'));
var newModuleComponent;
// Initialize the component and a mock scope
beforeEach(inject(function($componentController) {
newModuleComponent = $componentController('newModule', {});
}));
it('should ...', function() {
expect(1).to.equal(1);
});
});

View file

@ -1,325 +0,0 @@
'use strict';
const angular = require('angular');
/*@ngInject*/
export function newModuleController($scope,$filter,customModules,ansible,YAML) {
var newModuleCtrl = this;
// List of options types for module parameters to be displayed in UI
newModuleCtrl.optionTypes = ['str','list','dict','bool','int','float','path','raw','jsonarg','json','bytes','bits'];
var parentCtrl = $scope.$parent.customModulesCtrl;
// Define the default module object
var defaultModule = {
module:null,
short_description:"",
description:"",
version_added:"",
author:"",
notes: "",
requirements: "",
options:[
{
name:"parameter1",
description: 'Description of parameter 1',
required: true,
default: null,
choices: '"choice1", "choice2"',
aliases: '"option1", "argument1"',
type: ""
}
]
};
// Load Default Template
newModuleCtrl.loadDefaultTemplate = function(){
newModuleCtrl.newModule = angular.copy(defaultModule);
parentCtrl.selectedModule.module_code = "Loading Template..";
customModules.show('template.py',function(response) {
parentCtrl.selectedModule.module_code = response.data.split("Stream :: close")[0];
});
};
// Watch for change in new module and update Documentation, parameters and examples dynamically
$scope.$watch('newModuleCtrl.newModule',function(newValue,oldValue){
if(!newValue)return;
updateDocumentation(newValue);
updateParameters(newValue);
updateExamples(newValue);
},true);
/**
* Update parameters
* Use regex to identify patterns in code and update parameter section dynamically
* */
var updateParameters = function(newValue){
newValue = angular.copy(newValue);
var parameters_definition_lines = [];
var parameters_retreive_lines = [];
angular.forEach(newValue.options,function(option){
if(option.name) {
var line = option.name + "=dict(";
var line_arguments = [];
if (option.required)line_arguments.push("required=True");
if (!option.required && option.default)line_arguments.push("default='" + option.default + "'");
if (option.type)line_arguments.push("type='" + option.type + "'");
if (option.choices)line_arguments.push("choices=[" + option.choices + "]");
if (option.aliases)line_arguments.push("aliases=[" + option.aliases + "]");
line += line_arguments.join(",");
line += ")";
parameters_definition_lines.push(line);
parameters_retreive_lines.push(option.name + ' = module.params[\'' + option.name + '\']')
}
});
var parameters_definition_string = parameters_definition_lines.join(",\n ");
var parameters_retreive_string = parameters_retreive_lines.join("\n ");
var re = /(# <--Begin Parameter Definition -->\s+ )([^]+)(\s+ # <--END Parameter Definition -->)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re,"$1" + parameters_definition_string + "$3");
var supports_check_mode_string = '\n';
if(newValue.supports_check_mode){
supports_check_mode_string = '\n , supports_check_mode=True\n'
}
var re2 = /(# <--Begin Supports Check Mode -->)([^]+)( # <--End Supports Check Mode -->)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re2,"$1" + supports_check_mode_string + "$3");
var re3 = /(# <--Begin Retreiving Parameters -->\s+ )([^]+)(\s+ # <--End Retreiving Parameters -->)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re3,"$1" + parameters_retreive_string + "$3");
};
/**
* Update Documentation
* Update documentation section dynamically based on user input
*
* */
var updateDocumentation = function(newValue){
newValue = angular.copy(newValue);
newValue.options = convertOptionsToObject(newValue.options);
delete newValue['supports_check_mode'];
if(newValue.description)
newValue.description = newValue.description.split(";");
if(newValue.notes)
newValue.notes = newValue.notes.split(";");
if(newValue.requirements)
newValue.requirements = newValue.requirements.split(";");
newModuleCtrl.documentation_yaml = '---\n' + $filter('json2yaml')(angular.toJson(newValue)).toString().replace(/__dot__/g,".");
//var re = /(.*DOCUMENTATION = '''\n)([^]+?)(\n'''.*)/;
var re = /([^]+DOCUMENTATION = '''\s+)([^]+?)(\s+'''[^]+)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re,'$1' + newModuleCtrl.documentation_yaml + '$3');
};
var updateExamples = function(newValue){
newValue = angular.copy(newValue);
var moduleCopy = {
};
moduleCopy[newValue.module] = convertOptionsToExampleObject(newValue.options);
newModuleCtrl.example_yaml = YAML.stringify(moduleCopy,4);
//var re = /(.*DOCUMENTATION = '''\n)([^]+?)(\n'''.*)/;
var re = /([^]+EXAMPLES = '''[^]+# <-- -->\s+)([^]+?)(\s+# <-- \/ -->\s+'''[^]+)/;
parentCtrl.selectedModule.module_code = parentCtrl.selectedModule.module_code.replace(re,'$1' + newModuleCtrl.example_yaml + '$3');
};
/**
* Convert Options to Object
* */
var convertOptionsToObject = function(options){
var result = {};
angular.forEach(options,function(option){
if(option.name){
result[option.name] = {
description: option.description
};
if(option.required)
result[option.name]['required'] = "True";
else
delete result[option.name]['required'];
if(!option.required && option.default)
result[option.name]['default'] = option.default;
if(option.choices){
result[option.name]['choices'] = "[" + option.choices + "]"
}
if(option.aliases){
result[option.name]['aliases'] = "[" + option.aliases + "]"
}
}
});
return result
};
/**
* Convert Options to Example Object
* */
var convertOptionsToExampleObject = function(options){
var result = {};
angular.forEach(options,function(option){
if(option.name){
result[option.name] = "value";
}
});
return result
};
/**
* Convert Options to Array
* */
var convertOptionsToArrays = function(options){
var result = [];
angular.forEach(options,function(value,key){
var option = {
name: key,
description: value.description,
required: value.required,
default:value.default
};
if(value.choices && value.choices.length)
option['choices'] = value.choices.map(function(item){return ('"' + item + '"')}).join(",");
if(value.aliases && value.aliases.length)
option['aliases'] = value.aliases.map(function(item){return ('"' + item + '"')}).join(",");
result.push(option)
});
return result
};
/**
* Save New Module
*
* */
newModuleCtrl.saveNewModule = function(){
newModuleCtrl.saving = true;
customModules.save(newModuleCtrl.newModule.module + '.py',parentCtrl.selectedModule.module_code,function(response){
newModuleCtrl.saving = false;
parentCtrl.getCustomModules();
ansible.getAnsibleModules(function(response){
}, function(response){
},null,true);
newModuleCtrl.cancelNewModule();
},function(response){
newModuleCtrl.saving = false;
console.error(response.data)
})
};
/**
* Cancel New Module
*
* */
newModuleCtrl.cancelNewModule = function(){
parentCtrl.showNewModuleForm.value = false;
parentCtrl.showModuleCode(parentCtrl.selectedModule.module.name)
};
/**
* Get properties from code to display in UI
*
* */
var getPropertiesFromCode = function(module_code){
//var re = /([^]+DOCUMENTATION = '''\n)([^]+?)(\n'''[^]+)/;
var re = /([^]+DOCUMENTATION = '''\s+)([^]+?)(\s+'''[^]+)/;
var module_string = parentCtrl.selectedModule.module_code.replace(re,'$2');
newModuleCtrl.newModule = YAML.parse(module_string);
newModuleCtrl.newModule.options = convertOptionsToArrays(newModuleCtrl.newModule.options);
if(newModuleCtrl.newModule.description && newModuleCtrl.newModule.description.length)
newModuleCtrl.newModule.description = newModuleCtrl.newModule.description.join(";");
if(newModuleCtrl.newModule.notes && newModuleCtrl.newModule.notes.length)
newModuleCtrl.newModule.notes = newModuleCtrl.newModule.notes.join(";");
if(newModuleCtrl.newModule.requirements && newModuleCtrl.newModule.requirements.length)
newModuleCtrl.newModule.requirements = newModuleCtrl.newModule.requirements.join(";");
re = /([^]+# <--Begin Parameter Definition -->\s+ )([^]+)(\s+ # <--END Parameter Definition -->[^]+)/;
var parameter_string = parentCtrl.selectedModule.module_code.replace(re,"$2");
// Read property type form parameter definition
re = /\s+(.*?)=.*type=(.*?)[,\)].*/g;
var m;
while ((m = re.exec(parameter_string)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
if(m[1]){
angular.forEach(newModuleCtrl.newModule.options,function(option){
if(option.name === m[1]){
option.type = m[2].replace(/'/g,'')
}
})
}
}
};
$scope.$on('editModule', function(e) {
getPropertiesFromCode(newModuleCtrl.selected_module_code)
});
$scope.$on('newModule', function(e) {
newModuleCtrl.loadDefaultTemplate();
});
}
export default angular.module('webAppApp.new_module', [])
.controller('NewModuleController', newModuleController)
.name;

View file

@ -1,17 +0,0 @@
'use strict';
describe('Controller: NewModuleCtrl', function() {
// load the controller's module
beforeEach(module('webAppApp.new_module'));
var NewModuleCtrl;
// Initialize the controller and a mock scope
beforeEach(inject(function($controller) {
NewModuleCtrl = $controller('NewModuleCtrl', {});
}));
it('should ...', function() {
expect(1).to.equal(1);
});
});

View file

@ -1,4 +1,4 @@
<div class="row" ng-controller="NewModuleController as newModuleCtrl">
<div class="row">
<div class="panel">
<div class="panel panel-primary">
@ -8,25 +8,25 @@
<div class="col-md-4">
<p class="form-group">
<label>Module Name</label>
<input type="text" ng-model="newModuleCtrl.newModule.module" class="form-control" ng-required="true" placeholder="modulename">
<input type="text" ng-model="$ctrl.newModule.module" class="form-control" ng-required="true" placeholder="modulename">
</p>
</div>
<div class="col-md-2">
<p class="form-group">
<label>Version Added</label>
<input type="text" ng-model="newModuleCtrl.newModule.version_added" class="form-control" ng-required="true" placeholder="X.Y">
<input type="text" ng-model="$ctrl.newModule.version_added" class="form-control" ng-required="true" placeholder="X.Y">
</p>
</div>
<div class="col-md-2">
<p class="form-group">
<label>Check Mode</label>
<label class="checkbox-inline"><input ng-model="newModuleCtrl.newModule.supports_check_mode" type="checkbox"></label>
<label class="checkbox-inline"><input ng-model="$ctrl.newModule.supports_check_mode" type="checkbox"></label>
</p>
</div>
<div class="col-md-4">
<p class="form-group">
<label>Author</label>
<input type="text" ng-model="newModuleCtrl.newModule.author" class="form-control" ng-required="true" placeholder="Your AWESOME name, @awesome-github-id">
<input type="text" ng-model="$ctrl.newModule.author" class="form-control" ng-required="true" placeholder="Your AWESOME name, @awesome-github-id">
</p>
</div>
</div>
@ -35,13 +35,13 @@
<div class="col-md-4">
<p class="form-group">
<label>Short Description</label>
<input type="text" ng-model="newModuleCtrl.newModule.short_description" class="form-control" ng-required="true" placeholder="This is a sentence describing the module">
<input type="text" ng-model="$ctrl.newModule.short_description" class="form-control" ng-required="true" placeholder="This is a sentence describing the module">
</p>
</div>
<div class="col-md-8">
<p class="form-group">
<label>Description</label>
<input type="text" ng-model="newModuleCtrl.newModule.description" class="form-control" ng-required="true" placeholder="Longer description of the module; You might include instructions">
<input type="text" ng-model="$ctrl.newModule.description" class="form-control" ng-required="true" placeholder="Longer description of the module; You might include instructions">
</p>
</div>
</div>
@ -49,12 +49,12 @@
<p class="form-group">
<label>Notes</label>
<input type="text" ng-model="newModuleCtrl.newModule.notes" class="form-control" ng-required="true" placeholder="Other things consumers of your module should know">
<input type="text" ng-model="$ctrl.newModule.notes" class="form-control" ng-required="true" placeholder="Other things consumers of your module should know">
</p>
<p class="form-group">
<label>Requirements</label>
<input type="text" ng-model="newModuleCtrl.newModule.requirements" class="form-control" ng-required="true" placeholder="List of required things separated by semicolon; like the factor package; or a specific platform">
<input type="text" ng-model="$ctrl.newModule.requirements" class="form-control" ng-required="true" placeholder="List of required things separated by semicolon; like the factor package; or a specific platform">
</p>
<div class="panel">
@ -88,7 +88,7 @@
</div>
</div>
<div ng-repeat="option in newModuleCtrl.newModule.options">
<div ng-repeat="option in $ctrl.newModule.options">
<div class="row">
<div class="col-md-2" style="padding:2px;">
@ -100,7 +100,7 @@
</div>
<div class="col-md-1" style="padding:2px;">
<select class="form-control" ng-model="option.type" ng-options="optionType for optionType in newModuleCtrl.optionTypes">
<select class="form-control" ng-model="option.type" ng-options="optionType for optionType in $ctrl.optionTypes">
</select>
</div>
@ -118,8 +118,8 @@
</div>
<div class="col-md-1" style="padding:2px;text-align: center;">
<div class="btn-group">
<label class="btn btn-default" uib-tooltip="Insert new row after" ng-click="newModuleCtrl.newModule.options.splice($index+1,0,{})" style="padding-top: 3px;padding-bottom: 3px;padding-left:5px;padding-right:5px;"><span class="fa fa-plus"></span></label>
<label class="btn btn-danger" uib-tooltip="Delete row" ng-click="newModuleCtrl.newModule.options.splice($index,1)" style="padding-top: 3px;padding-bottom: 3px; padding-left:5px; padding-right:5px;"><span class="fa fa-minus"></span></label>
<label class="btn btn-default" uib-tooltip="Insert new row after" ng-click="$ctrl.newModule.options.splice($index+1,0,{})" style="padding-top: 3px;padding-bottom: 3px;padding-left:5px;padding-right:5px;"><span class="fa fa-plus"></span></label>
<label class="btn btn-danger" uib-tooltip="Delete row" ng-click="$ctrl.newModule.options.splice($index,1)" style="padding-top: 3px;padding-bottom: 3px; padding-left:5px; padding-right:5px;"><span class="fa fa-minus"></span></label>
</div>
</div>
</div>
@ -135,8 +135,8 @@
</div>
<button class="btn btn-primary" ng-disabled="!newModuleCtrl.newModule.module" ng-click="newModuleCtrl.saveNewModule()"> Save <span ng-if="!newModuleCtrl.saving" class="fa fa-save"></span> <span ng-if="saving" class="fa fa-spin fa-spinner"></span> </button>
<button class="btn btn-default" confirm="Are you sure you want to discard the changes?" ng-click="newModuleCtrl.cancelNewModule()"> Cancel <span class="fa fa-times"></span> </button>
<button class="btn btn-primary" ng-disabled="!$ctrl.newModule.module" ng-click="$ctrl.saveNewModule()"> Save <span ng-if="!$ctrl.saving" class="fa fa-save"></span> <span ng-if="saving" class="fa fa-spin fa-spinner"></span> </button>
<button class="btn btn-default" confirm="Are you sure you want to discard the changes?" ng-click="$ctrl.cancelNewModule()"> Cancel <span class="fa fa-times"></span> </button>
</div>

View file

@ -99,11 +99,11 @@
<div>
<div class="row" style="padding-top: 20px;">
<div class="col-md-4"> <div class="md-whiteframe-23dp"><a href="https://www.udemy.com/learn-ansible" target="_blank"><img src="assets/images/rsz_course_image.png" /></a></div></div>
<div class="col-md-4"> <div class="md-whiteframe-23dp"><a href="https://www.udemy.com/learn-ansible/?couponCode=INSTRUCTOR" target="_blank"><img src="assets/images/rsz_course_image.png" /></a></div></div>
<div class="col-md-8">
<h1><i class="fa fa-graduation-cap" aria-hidden="true"></i> Learn Ansible</h1>
This course on <a href="https://www.udemy.com/learn-ansible" style="color: #37e937;">Udemy</a> introduces a beginner to basic fundamentals of Ansible with easy to do hands-on exercises that you can practice right in the browser. The course introduces basic use cases of Ansible followed by an introduction to Ansible Inventory, Playbooks, Modules, Variables, Conditionals, Loops and Roles. Each lecture is accompanied by a set of coding exercises giving the user a hands-on experience in developing Ansible Playbooks.
<div><a class="btn btn-success" href="https://www.udemy.com/learn-ansible" target="_blank"> <i class="fa fa-external-link" aria-hidden="true"></i> Start Learning Here </a></div>
This course on <a href="https://www.udemy.com/learn-ansible/?couponCode=INSTRUCTOR" style="color: #37e937;">Udemy</a> introduces a beginner to basic fundamentals of Ansible with easy to do hands-on exercises that you can practice right in the browser. The course introduces basic use cases of Ansible followed by an introduction to Ansible Inventory, Playbooks, Modules, Variables, Conditionals, Loops and Roles. Each lecture is accompanied by a set of coding exercises giving the user a hands-on experience in developing Ansible Playbooks.
<div><a class="btn btn-success" href="https://www.udemy.com/learn-ansible/?couponCode=INSTRUCTOR" target="_blank"> <i class="fa fa-external-link" aria-hidden="true"></i> Start Learning Here </a></div>
</div>
</div>

View file

@ -20,7 +20,7 @@
<ul class="nav navbar-nav navbar-right">
<li class="btn-github" ui-sref-active="active"><a target="_blank" href="https://github.com/mmumshad/ansible-playable/issues"><i class="fa fa-ticket" aria-hidden="true"></i></i> Report Issues</a></li>
<li class="btn-danger" ui-sref-active="active"><a target="_blank" href="https://www.udemy.com/learn-ansible"><i class="fa fa-graduation-cap" aria-hidden="true"></i> Learn Ansible</a></li>
<li class="btn-danger" ui-sref-active="active"><a target="_blank" href="https://www.udemy.com/learn-ansible/?couponCode=INSTRUCTOR"><i class="fa fa-graduation-cap" aria-hidden="true"></i> Learn Ansible</a></li>
<!--<li ng-hide="$ctrl.isLoggedIn()" ui-sref-active="active"><a ui-sref="signup">Sign up</a></li>-->
<li ng-hide="$ctrl.isLoggedIn()" ui-sref-active="active"><a ui-sref="login">Login</a></li>
<li ng-show="$ctrl.isLoggedIn()"><p class="navbar-text">Hello {{ $ctrl.getCurrentUser().name }}</p> </li>