demodalizing management jobs modal

This commit is contained in:
Jared Tabor
2015-07-22 15:08:46 -04:00
parent 4e6c97aa56
commit fb99bc1c04
25 changed files with 688 additions and 816 deletions

View File

@@ -30,9 +30,11 @@ import {JobsListController} from './controllers/Jobs';
import {PortalController} from './controllers/Portal'; import {PortalController} from './controllers/Portal';
import systemTracking from './system-tracking/main'; import systemTracking from './system-tracking/main';
import inventoryScripts from './inventory-scripts/main'; import inventoryScripts from './inventory-scripts/main';
import managementJobs from './management-jobs/main';
import routeExtensions from './shared/route-extensions/main'; import routeExtensions from './shared/route-extensions/main';
import breadcrumbs from './shared/breadcrumbs/main'; import breadcrumbs from './shared/breadcrumbs/main';
// modules // modules
import setupMenu from './setup-menu/main'; import setupMenu from './setup-menu/main';
import mainMenu from './main-menu/main'; import mainMenu from './main-menu/main';
@@ -84,6 +86,7 @@ var tower = angular.module('Tower', [
breadcrumbs.name, breadcrumbs.name,
systemTracking.name, systemTracking.name,
inventoryScripts.name, inventoryScripts.name,
managementJobs.name,
setupMenu.name, setupMenu.name,
mainMenu.name, mainMenu.name,
dashboard.name, dashboard.name,
@@ -183,8 +186,8 @@ var tower = angular.module('Tower', [
'AboutAnsibleHelpModal', 'AboutAnsibleHelpModal',
'SurveyQuestionFormDefinition', 'SurveyQuestionFormDefinition',
'PortalJobsListDefinition', 'PortalJobsListDefinition',
'ConfigureTowerHelper',
'ConfigureTowerJobsListDefinition',
'AdhocHelper', 'AdhocHelper',
'features', 'features',
'longDateFilter' 'longDateFilter'
@@ -944,9 +947,9 @@ var tower = angular.module('Tower', [
}]) }])
.run(['$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer', 'ClearScope', 'HideStream', 'Socket', .run(['$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer', 'ClearScope', 'HideStream', 'Socket',
'LoadConfig', 'Store', 'ShowSocketHelp', 'AboutAnsibleHelp', 'ConfigureTower', 'LoadConfig', 'Store', 'ShowSocketHelp', 'AboutAnsibleHelp',
function ($compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, Timer, ClearScope, HideStream, Socket, function ($compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, Timer, ClearScope, HideStream, Socket,
LoadConfig, Store, ShowSocketHelp, AboutAnsibleHelp, ConfigureTower) { LoadConfig, Store, ShowSocketHelp, AboutAnsibleHelp) {
var sock; var sock;
@@ -1154,13 +1157,6 @@ var tower = angular.module('Tower', [
$location.path('/home/'); $location.path('/home/');
}; };
$rootScope.configureTower = function(){
ConfigureTower({
scope: $rootScope,
parent_scope: $rootScope
});
};
}); // end of 'ConfigReady' }); // end of 'ConfigReady'

View File

@@ -1,657 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name helpers.function:ConfigureTower
* @description
* Schedules Helper
*
* Display the scheduler widget in a dialog
*
*/
import listGenerator from '../shared/list-generator/main';
export default
angular.module('ConfigureTowerHelper', [ 'Utilities', 'RestServices', 'SchedulesHelper', 'SearchHelper', 'PaginationHelpers', listGenerator.name, 'ModalDialog',
'GeneratorHelpers'])
.factory('ConfigureTower', ['Wait', '$location' , '$compile', 'CreateDialog', 'ConfigureTowerJobsList', 'generateList', 'GetBasePath' , 'SearchInit' , 'PaginateInit', 'PlaybookRun', 'LoadSchedulesScope',
'SchedulesList', 'SchedulesControllerInit' , 'ConfigureTowerSchedule', 'Rest' , 'ProcessErrors',
function(Wait, $location, $compile, CreateDialog, ConfigureTowerJobsList, GenerateList, GetBasePath, SearchInit, PaginateInit, PlaybookRun, LoadSchedulesScope,
SchedulesList, SchedulesControllerInit, ConfigureTowerSchedule, Rest, ProcessErrors) {
return function(params) {
// Set modal dimensions based on viewport width
var scope = params.scope.$new(),
parent_scope = params.scope,
callback = 'OpenConfig',
defaultUrl = GetBasePath('system_job_templates'),
list = ConfigureTowerJobsList,
view = GenerateList, e,
scheduleUrl = GetBasePath('system_job_templates'),
buttons = [
{
"label": "Close",
"onClick": function() {
// $(this).dialog('close');
scope.cancelConfigure();
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "configure-close-button"
}
];
scope.cleanupJob = true;
if(scope.removeOpenConfig) {
scope.removeOpenConfig();
}
scope.removeOpenConfig = scope.$on('OpenConfig', function() {
$('#configure-tower-dialog').dialog('open');
$('#configure-close-button').focus();
$('#configure-close-button').blur();
});
view.inject( list, {
id : 'configure-jobs',
mode: 'edit',
scope: scope,
breadCrumbs: false,
showSearch: false
});
SearchInit({
scope: scope,
set: 'configure_jobs',
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl
});
scope.search(list.iterator);
SchedulesControllerInit({
scope: scope,
parent_scope: parent_scope,
// list: list
});
CreateDialog({
id: 'configure-tower-dialog',
title: 'Management Jobs',
target: 'configure-tower-dialog',
scope: scope,
buttons: buttons,
width: 670,
height: 800,
minWidth: 400,
callback: callback,
onClose: function () {
// Destroy on close
$('.tooltip').each(function () {
// Remove any lingering tooltip <div> elements
$(this).remove();
});
$('.popover').each(function () {
// remove lingering popover <div> elements
$(this).remove();
});
$("#configure-jobs").show();
$("#configure-schedules-form-container").hide();
$('#configure-schedules-list').empty();
$('#configure-schedules-form').empty();
$('#configure-schedules-detail').empty();
$('#configure-tower-dialog').hide();
$(this).dialog('destroy');
scope.cancelConfigure();
},
});
// Cancel
scope.cancelConfigure = function () {
try {
$('#configure-tower-dialog').dialog('close');
$("#configure-save-button").remove();
}
catch(e) {
//ignore
}
if (scope.searchCleanup) {
scope.searchCleanup();
}
// if (!Empty(parent_scope) && parent_scope.restoreSearch) {
// parent_scope.restoreSearch();
// }
else {
Wait('stop');
}
};
scope.submitCleanupJob = function(id, name){
defaultUrl = GetBasePath('system_job_templates')+id+'/launch/';
CreateDialog({
id: 'prompt-for-days-facts',
title: name,
scope: scope,
width: 500,
height: 470,
minWidth: 200,
callback: 'PromptForDaysFacts',
onOpen: function(){
scope.keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.granularity_keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
e = angular.element(document.getElementById('prompt_for_days_facts_form'));
scope.prompt_for_days_facts_form.keep_amount.$setViewValue(30);
scope.prompt_for_days_facts_form.granularity_keep_amount.$setViewValue(1);
$compile(e)(scope);
scope.keep_unit = scope.keep_unit_choices[0];
scope.granularity_keep_unit = scope.granularity_keep_unit_choices[1];
// this is a work-around for getting awMax to work (without
// clearing out the form)
scope.$watch('keep_amount', function(newVal) {
if (!newVal && newVal !== 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (isNaN(newVal)) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal < 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal > 9999) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else {
$('#prompt-for-days-facts-launch').prop("disabled", false);
}
});
scope.$watch('granularity_keep_amount', function(newVal2) {
if (!newVal2 && newVal2 !== 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (isNaN(newVal2)) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal2 < 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal2 > 9999) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else {
$('#prompt-for-days-facts-launch').prop("disabled", false);
}
});
},
buttons: [{
"label": "Cancel",
"onClick": function() {
$(this).dialog('close');
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "prompt-for-days-facts-cancel"
},{
"label": "Launch",
"onClick": function() {
var extra_vars = {
"older_than": scope.keep_amount+scope.keep_unit.value,
"granularity": scope.granularity_keep_amount+scope.granularity_keep_unit.value
},
data = {};
data.extra_vars = JSON.stringify(extra_vars);
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function() {
Wait('stop');
$("#prompt-for-days-facts").dialog("close");
$("#configure-tower-dialog").dialog('close');
$location.path('/jobs/');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed updating job ' + scope.job_template_id + ' with variables. POST returned: ' + status });
});
},
"icon": "fa-rocket",
"class": "btn btn-primary",
"id": "prompt-for-days-facts-launch"
}]
});
if (scope.removePromptForDays) {
scope.removePromptForDays();
}
scope.removePromptForDays = scope.$on('PromptForDaysFacts', function() {
// $('#configure-tower-dialog').dialog('close');
$('#prompt-for-days-facts').show();
$('#prompt-for-days-facts').dialog('open');
Wait('stop');
});
};
scope.submitJob = function (id, name) {
Wait('start');
if(this.configure_job.job_type === "cleanup_facts"){
scope.submitCleanupJob(id, name);
}
else {
defaultUrl = GetBasePath('system_job_templates')+id+'/launch/';
CreateDialog({
id: 'prompt-for-days' ,
title: name,
scope: scope,
width: 500,
height: 300,
minWidth: 200,
callback: 'PromptForDays',
onOpen: function(){
e = angular.element(document.getElementById('prompt_for_days_form'));
scope.prompt_for_days_form.days_to_keep.$setViewValue(30);
$compile(e)(scope);
// this is a work-around for getting awMax to work (without
// clearing out the form)
scope.$watch('days_to_keep', function(newVal) { // oldVal, scope) { // unused params get caught by jshint
if (!newVal && newVal !== 0) {
$('#prompt-for-days-launch').prop("disabled", true);
} else if (isNaN(newVal)) {
$('#prompt-for-days-launch').prop("disabled", true);
} else if (newVal < 0) {
$('#prompt-for-days-launch').prop("disabled", true);
} else if (newVal > 9999) {
$('#prompt-for-days-launch').prop("disabled", true);
} else {
$('#prompt-for-days-launch').prop("disabled", false);
}
});
},
buttons: [{
"label": "Cancel",
"onClick": function() {
$(this).dialog('close');
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "prompt-for-days-cancel"
},{
"label": "Launch",
"onClick": function() {
var extra_vars = {"days": scope.days_to_keep },
data = {};
data.extra_vars = JSON.stringify(extra_vars);
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function() {
Wait('stop');
$("#prompt-for-days").dialog("close");
$("#configure-tower-dialog").dialog('close');
$location.path('/jobs/');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed updating job ' + scope.job_template_id + ' with variables. POST returned: ' + status });
});
},
"icon": "fa-rocket",
"class": "btn btn-primary",
"id": "prompt-for-days-launch"
}]
});
if (scope.removePromptForDays) {
scope.removePromptForDays();
}
scope.removePromptForDays = scope.$on('PromptForDays', function() {
// $('#configure-tower-dialog').dialog('close');
$('#prompt-for-days').show();
$('#prompt-for-days').dialog('open');
Wait('stop');
});
}
};
scope.configureSchedule = function(id, name) {
if (id === 4) {
scope.isFactCleanup = true;
scope.keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.granularity_keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.prompt_for_days_facts_form.keep_amount.$setViewValue(30);
scope.prompt_for_days_facts_form.granularity_keep_amount.$setViewValue(1);
scope.keep_unit = scope.keep_unit_choices[0];
scope.granularity_keep_unit = scope.granularity_keep_unit_choices[1];
} else {
scope.isFactCleanup = false;
}
Rest.setUrl(scheduleUrl+id+'/schedules/');
Rest.get()
.success(function(data) {
if(data.count>0){
scope.days=data.results[0].extra_data.days;
ConfigureTowerSchedule({
scope: scope,
mode: 'edit',
url: scheduleUrl+id+'/schedules/'
});
} else {
ConfigureTowerSchedule({
scope: scope,
mode: 'add',
url: scheduleUrl+id+'/schedules/',
name: name
});
}
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed getting schedule information' });
});
};
parent_scope.refreshJobs = function(){
scope.search(SchedulesList.iterator);
};
};
}])
.factory('ConfigureTowerSchedule', ['$compile','SchedulerInit', 'Rest', 'Wait', 'SetSchedulesInnerDialogSize', 'SchedulePost', 'ProcessErrors', 'GetBasePath', 'Empty', 'Prompt',
function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, SchedulePost, ProcessErrors, GetBasePath, Empty, Prompt) {
return function(params) {
var parent_scope = params.scope,
mode = params.mode, // 'add' or 'edit'
url = params.url,
scope = parent_scope.$new(),
id = params.id || undefined,
name = params.name || undefined,
schedule = {},
scheduler,
target,
showForm,
list,
detail,
restoreList,
container,
elem;
Wait('start');
// $('#configure-jobs').hide();
detail = $('#configure-schedules-detail').hide();
list = $('#configure-schedules-list');
target = $('#configure-schedules-form');
container = $('#configure-schedules-form-container');
$("#configure-jobs").show();
$("#configure-schedules-form-container").hide();
scope.mode = mode;
// Clean up any lingering stuff
container.hide();
target.empty();
$('.tooltip').each(function () {
$(this).remove();
});
$('.popover').each(function () {
$(this).remove();
});
$("#configure-cancel-button").after('<button type="button" class="btn btn-primary btn-sm" id="configure-save-button" ng-click="saveScheduleForm()" style="margin-left:5px"><i class="fa fa-check"></i> Save</button>');
elem = angular.element(document.getElementById('configure-schedules-form-container'));
$compile(elem)(scope);
if (scope.removeScheduleReady) {
scope.removeScheduleReady();
}
scope.removeScheduleReady = scope.$on('ScheduleReady', function() {
// Insert the scheduler widget into the hidden div
scheduler = SchedulerInit({ scope: scope, requireFutureStartTime: false });
scheduler.inject('configure-schedules-form', false);
scheduler.injectDetail('configure-schedules-detail', false);
scheduler.clear();
scope.formShowing = true;
scope.showRRuleDetail = false;
scope.schedulesTitle = (mode === 'edit') ? 'Edit Schedule' : 'Create Schedule';
// display the scheduler widget
showForm = function() {
$('#configure-jobs').show('slide', { direction: 'left' }, 500);
$('#configure-jobs').hide();
Wait('stop');
$('#configure-schedules-overlay').width($('#configure-schedules-tab')
.width()).height($('#configure-schedules-tab').height()).show();
container.width($('#configure-schedules-tab').width() - 18);
SetSchedulesInnerDialogSize();
container.show('slide', { direction: 'right' }, 300);
// scope.schedulerPurgeDays = (!Empty(scope.days)) ? Number(scope.days) : 30;
target.show();
if (scope.isFactCleanup) {
scope.$watch('scheduler_form.keep_amount.$modelValue', function(newVal) {
if (!newVal && newVal !== 0) {
$('#configure-save-button').prop("disabled", true);
} else if (isNaN(newVal)) {
$('#configure-save-button').prop("disabled", true);
} else if (newVal < 0) {
$('#configure-save-button').prop("disabled", true);
} else if (newVal > 9999) {
$('#configure-save-button').prop("disabled", true);
} else {
$('#configure-save-button').prop("disabled", false);
}
});
scope.$watch('scheduler_form.granularity_keep_amount.$modelValue', function(newVal2) {
if (!newVal2 && newVal2 !== 0) {
$('#configure-save-button').prop("disabled", true);
} else if (isNaN(newVal2)) {
$('#configure-save-button').prop("disabled", true);
} else if (newVal2 < 0) {
$('#configure-save-button').prop("disabled", true);
} else if (newVal2 > 9999) {
$('#configure-save-button').prop("disabled", true);
} else {
$('#configure-save-button').prop("disabled", false);
}
});
}
if(mode==="add"){
scope.$apply(function(){
scope.schedulerPurgeDays = 30;
scope.schedulerName = name+' Schedule';
});
}
if (mode === 'edit') {
scope.$apply(function() {
scheduler.setRRule(schedule.rrule);
scheduler.setName(schedule.name);
scope.schedulerPurgeDays = (!Empty(scope.days)) ? Number(scope.days) : 30;
});
}
};
setTimeout(function() { showForm(); }, 1000);
});
restoreList = function() {
// $('#group-save-button').prop('disabled', false);
$('#configure-jobs').show('slide', { direction: 'right' }, 500);
// $('#configure-jobs').width($('#configure-jobs').width()).height($('#configure-jobs').height()).hide();
// parent_scope.refreshSchedules();
list.show('slide', { direction: 'right' }, 500);
$('#configure-schedules-overlay').width($('#configure-schedules-tab').width()).height($('#configure-schedules-tab').height()).hide();
parent_scope.refreshSchedules();
};
scope.showScheduleDetail = function() {
if (scope.formShowing) {
if (scheduler.isValid()) {
detail.width($('#configure-schedules-form').width()).height($('#configure-schedules-form').height());
target.hide();
detail.show();
scope.formShowing = false;
}
}
else {
detail.hide();
target.show();
scope.formShowing = true;
}
};
if (scope.removeScheduleSaved) {
scope.removeScheduleSaved();
}
scope.removeScheduleSaved = scope.$on('ScheduleSaved', function() {
Wait('stop');
$("#configure-save-button").remove();
container.hide('slide', { direction: 'left' }, 500, restoreList);
scope.$destroy();
});
scope.saveScheduleForm = function() {
var extra_vars;
if (scheduler.isValid()) {
scope.schedulerIsValid = true;
url = (mode==="edit") ? GetBasePath('schedules')+id+'/' : url;
if (scope.isFactCleanup) {
extra_vars = {
"older_than": scope.scheduler_form.keep_amount.$viewValue + scope.scheduler_form.keep_unit.$viewValue.value,
"granularity": scope.scheduler_form.granularity_keep_amount.$viewValue + scope.scheduler_form.granularity_keep_unit.$viewValue.value
};
} else {
extra_vars = {
"days" : scope.scheduler_form.schedulerPurgeDays.$viewValue
};
}
schedule.extra_data = JSON.stringify(extra_vars);
SchedulePost({
scope: scope,
url: url,
scheduler: scheduler,
callback: 'ScheduleSaved',
mode: mode,
schedule: schedule
});
}
else {
scope.schedulerIsValid = false;
}
};
scope.deleteSystemSchedule = function(){
var hdr = 'Delete Schedule',
action = function () {
Wait('start');
Rest.setUrl(schedule.url);
Rest.destroy()
.success(function () {
$('#prompt-modal').modal('hide');
Wait('stop');
// scope.$emit(callback, id);
scope.cancelScheduleForm();
})
.error(function (data, status) {
try {
$('#prompt-modal').modal('hide');
}
catch(e) {
// ignore
}
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url +
' failed. DELETE returned: ' + status });
});
};
Prompt({
hdr: hdr,
body: "<div class=\"alert alert-info\">Are you sure you want to delete the <em>" + scope.schedulerName + "</em> schedule?</div>",
action: action,
backdrop: false
});
};
scope.cancelScheduleForm = function() {
container.hide('slide', { direction: 'right' }, 500, restoreList);
$("#configure-save-button").remove();
scope.$destroy();
};
if (mode === 'edit') {
// Get the existing record
Rest.setUrl(url); //GetBasePath('schedules')+id+'/');
Rest.get()
.success(function(data) {
schedule = data.results[0];
id = schedule.id;
if (!/DTSTART/.test(schedule.rrule)) {
schedule.rrule += ";DTSTART=" + schedule.dtstart.replace(/\.\d+Z$/,'Z');
}
schedule.rrule = schedule.rrule.replace(/ RRULE:/,';');
schedule.rrule = schedule.rrule.replace(/DTSTART:/,'DTSTART=');
scope.$emit('ScheduleReady');
})
.error(function(data,status){
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed to get: ' + url + ' GET returned: ' + status });
});
}
else {
scope.$emit('ScheduleReady');
}
};
}]);

View File

@@ -75,8 +75,10 @@ export default
}; };
}]) }])
.factory('EditSchedule', ['SchedulerInit', 'ShowSchedulerModal', 'Wait', 'Rest', 'ProcessErrors', 'GetBasePath', 'SchedulePost', .factory('EditSchedule', ['SchedulerInit', 'ShowSchedulerModal', 'Wait',
function(SchedulerInit, ShowSchedulerModal, Wait, Rest, ProcessErrors, GetBasePath, SchedulePost) { 'Rest', 'ProcessErrors', 'GetBasePath', 'SchedulePost', 'Empty', '$routeParams',
function(SchedulerInit, ShowSchedulerModal, Wait, Rest, ProcessErrors,
GetBasePath, SchedulePost, Empty, $routeParams) {
return function(params) { return function(params) {
var scope = params.scope, var scope = params.scope,
id = params.id, id = params.id,
@@ -84,6 +86,68 @@ export default
schedule, scheduler, schedule, scheduler,
url = GetBasePath('schedules') + id + '/'; url = GetBasePath('schedules') + id + '/';
function setGranularity(){
var a,b, prompt_for_days,
keep_unit,
granularity,
granularity_keep_unit;
if(scope.cleanupJob){
scope.schedulerPurgeDays = Number(schedule.extra_data.days);
// scope.scheduler_form.schedulerPurgeDays.$setViewValue( Number(schedule.extra_data.days));
}
else if(scope.isFactCleanup){
scope.keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.granularity_keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
// the API returns something like 20w or 1y
a = schedule.extra_data.older_than; // "20y"
b = schedule.extra_data.granularity; // "1w"
prompt_for_days = Number(_.initial(a,1).join(''));
keep_unit = _.last(a); // "y"
granularity = Number(_.initial(b,1).join(''));
granularity_keep_unit = _.last(b); // "w"
scope.prompt_for_days_facts_form.keep_amount.$setViewValue(prompt_for_days);
scope.prompt_for_days_facts_form.granularity_keep_amount.$setViewValue(granularity);
scope.keep_unit = _.find(scope.keep_unit_choices, function(i){
return i.value === keep_unit;
});
scope.granularity_keep_unit =_.find(scope.granularity_keep_unit_choices, function(i){
return i.value === granularity_keep_unit;
});
}
}
if(!Empty($routeParams.management_job)) {
if(scope.management_job.id === 4){
scope.isFactCleanup = true;
} else {
scope.cleanupJob = true;
}
}
if (scope.removeDialogReady) { if (scope.removeDialogReady) {
scope.removeDialogReady(); scope.removeDialogReady();
} }
@@ -94,6 +158,10 @@ export default
scope.$apply(function() { scope.$apply(function() {
scheduler.setRRule(schedule.rrule); scheduler.setRRule(schedule.rrule);
scheduler.setName(schedule.name); scheduler.setName(schedule.name);
if(!Empty(scope.management_job)){
setGranularity();
}
}); });
}, 300); }, 300);
}); });
@@ -112,7 +180,6 @@ export default
} }
schedule.rrule = schedule.rrule.replace(/ RRULE:/,';'); schedule.rrule = schedule.rrule.replace(/ RRULE:/,';');
schedule.rrule = schedule.rrule.replace(/DTSTART:/,'DTSTART='); schedule.rrule = schedule.rrule.replace(/DTSTART:/,'DTSTART=');
ShowSchedulerModal({ scope: scope, callback: 'DialogReady', title: 'Edit Schedule' }); ShowSchedulerModal({ scope: scope, callback: 'DialogReady', title: 'Edit Schedule' });
scope.showRRuleDetail = false; scope.showRRuleDetail = false;
}); });
@@ -141,6 +208,8 @@ export default
}); });
}; };
$('#scheduler-tabs li a').on('shown.bs.tab', function(e) { $('#scheduler-tabs li a').on('shown.bs.tab', function(e) {
if ($(e.target).text() === 'Details') { if ($(e.target).text() === 'Details') {
if (!scheduler.isValid()) { if (!scheduler.isValid()) {
@@ -181,6 +250,43 @@ export default
else if (!Empty($routeParams.id)) { else if (!Empty($routeParams.id)) {
url += $routeParams.id + '/schedules/'; url += $routeParams.id + '/schedules/';
} }
else if (!Empty($routeParams.management_job)) {
url += $routeParams.management_job + '/schedules/';
if(scope.management_job.id === 4){
scope.isFactCleanup = true;
scope.keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.granularity_keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.prompt_for_days_facts_form.keep_amount.$setViewValue(30);
scope.prompt_for_days_facts_form.granularity_keep_amount.$setViewValue(1);
scope.keep_unit = scope.keep_unit_choices[0];
scope.granularity_keep_unit = scope.granularity_keep_unit_choices[1];
}
else {
scope.cleanupJob = true;
}
}
if (scope.removeDialogReady) { if (scope.removeDialogReady) {
scope.removeDialogReady(); scope.removeDialogReady();
@@ -239,7 +345,7 @@ export default
mode = params.mode, mode = params.mode,
schedule = (params.schedule) ? params.schedule : {}, schedule = (params.schedule) ? params.schedule : {},
callback = params.callback, callback = params.callback,
newSchedule, rrule; newSchedule, rrule, extra_vars;
if (scheduler.isValid()) { if (scheduler.isValid()) {
Wait('start'); Wait('start');
@@ -248,6 +354,20 @@ export default
schedule.name = newSchedule.name; schedule.name = newSchedule.name;
schedule.rrule = RRuleToAPI(rrule.toString()); schedule.rrule = RRuleToAPI(rrule.toString());
schedule.description = (/error/.test(rrule.toText())) ? '' : rrule.toText(); schedule.description = (/error/.test(rrule.toText())) ? '' : rrule.toText();
if (scope.isFactCleanup) {
extra_vars = {
"older_than": scope.scheduler_form.keep_amount.$viewValue + scope.scheduler_form.keep_unit.$viewValue.value,
"granularity": scope.scheduler_form.granularity_keep_amount.$viewValue + scope.scheduler_form.granularity_keep_unit.$viewValue.value
};
} else if (scope.cleanupJob) {
extra_vars = {
"days" : scope.scheduler_form.schedulerPurgeDays.$viewValue
};
}
schedule.extra_data = JSON.stringify(extra_vars);
Rest.setUrl(url); Rest.setUrl(url);
if (mode === 'add') { if (mode === 'add') {
Rest.post(schedule) Rest.post(schedule)
@@ -442,8 +562,10 @@ export default
}]) }])
.factory('SchedulesControllerInit', ['$location', 'ToggleSchedule', 'DeleteSchedule', 'EditSchedule', 'AddSchedule', .factory('SchedulesControllerInit', ['$location', 'ToggleSchedule',
function($location, ToggleSchedule, DeleteSchedule, EditSchedule, AddSchedule) { 'DeleteSchedule', 'EditSchedule', 'AddSchedule',
function($location, ToggleSchedule, DeleteSchedule, EditSchedule,
AddSchedule) {
return function(params) { return function(params) {
var scope = params.scope, var scope = params.scope,
parent_scope = params.parent_scope, parent_scope = params.parent_scope,

View File

@@ -39,6 +39,6 @@ export default {
}); });
}); });
} }
], ]
} }
}; };

View File

@@ -41,6 +41,13 @@ export default function(){
ngClick: 'addCustomInv()', ngClick: 'addCustomInv()',
awToolTip: 'Create a new credential' awToolTip: 'Create a new credential'
}, },
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
icon: "icon-comments-alt",
mode: 'edit',
awFeature: 'activity_streams'
}
}, },
fieldActions: { fieldActions: {

View File

@@ -7,11 +7,11 @@
export default export default
[ '$rootScope','Wait', 'generateList', 'inventoryScriptsListObject', [ '$rootScope','Wait', 'generateList', 'inventoryScriptsListObject',
'GetBasePath' , 'SearchInit' , 'PaginateInit', 'GetBasePath' , 'SearchInit' , 'PaginateInit',
'Rest' , 'ProcessErrors', 'Prompt', 'transitionTo', 'Rest' , 'ProcessErrors', 'Prompt', 'transitionTo', 'Stream',
function( function(
$rootScope,Wait, GenerateList, inventoryScriptsListObject, $rootScope,Wait, GenerateList, inventoryScriptsListObject,
GetBasePath, SearchInit, PaginateInit, GetBasePath, SearchInit, PaginateInit,
Rest, ProcessErrors, Prompt, transitionTo Rest, ProcessErrors, Prompt, transitionTo, Stream
) { ) {
var scope = $rootScope.$new(), var scope = $rootScope.$new(),
defaultUrl = GetBasePath('inventory_scripts'), defaultUrl = GetBasePath('inventory_scripts'),
@@ -19,12 +19,8 @@ export default
view = GenerateList; view = GenerateList;
view.inject( list, { view.inject( list, {
id : 'inventory_scripts',
mode: 'edit', mode: 'edit',
scope: scope, scope: scope
breadCrumbs: false,
activityStream: false,
showSearch: true
}); });
SearchInit({ SearchInit({
@@ -46,6 +42,11 @@ export default
inventory_script: this.inventory_script inventory_script: this.inventory_script
}); });
}; };
scope.showActivity = function () {
Stream({ scope: scope });
};
scope.deleteCustomInv = function(id, name){ scope.deleteCustomInv = function(id, name){
var action = function () { var action = function () {

View File

@@ -1,16 +1,6 @@
<breadcrumbs> <breadcrumbs>
<breadcrumb path="/setup" title="Setup"></breadcrumb> <breadcrumb path="/setup" title="Setup"></breadcrumb>
<breadcrumb path="/inventory_scripts" title="Inventory Scripts"></breadcrumb> <breadcrumb path="/inventory_scripts" title="Inventory Scripts"></breadcrumb>
<breadcrumb
path="/inventory_scripts/add"
title="Create Inventory Script"
ng-if="mode == 'add'">
</breadcrumb>
<breadcrumb
path="/inventory_scripts/{{source_script.id}}"
title="{{inventory_scripts}}"
ng-if="organization_id">
</breadcrumb>
</breadcrumbs> </breadcrumbs>
<div class="tab-pane" id="inventory_scripts"> <div class="tab-pane" id="inventory_scripts">

View File

@@ -8,7 +8,7 @@ export default {
name: 'inventoryScriptsList', name: 'inventoryScriptsList',
route: '/inventory_scripts', route: '/inventory_scripts',
templateUrl: '/static/js/inventory-scripts/list/list.partial.html', templateUrl: '/static/js/inventory-scripts/list/list.partial.html',
controller: 'listController', controller: 'inventoryScriptsListController',
resolve: { resolve: {
features: ['FeaturesService', function(FeaturesService) { features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get(); return FeaturesService.get();

View File

@@ -1,25 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
var rest, getBasePath;
export default
[ 'Rest',
'GetBasePath',
function(_rest, _getBasePath) {
rest = _rest;
getBasePath = _getBasePath;
return deleteInventoryScript;
}
];
function deleteInventoryScript(id) {
var url = getBasePath('inventory_scripts');
url = url + id;
rest.setUrl(url);
return rest.destroy();
}

View File

@@ -9,7 +9,7 @@ import controller from './list.controller';
export default export default
angular.module('inventoryScriptsList', []) angular.module('inventoryScriptsList', [])
.controller('listController', controller) .controller('inventoryScriptsListController', controller)
.config(['$routeProvider', function($routeProvider) { .config(['$routeProvider', function($routeProvider) {
var url = route.route; var url = route.route;
delete route.route; delete route.route;

View File

@@ -0,0 +1,287 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
// import listGenerator from 'tower/shared/list-generator/main';
export default
[ 'Wait', '$location' , '$compile', 'CreateDialog', 'generateList',
'GetBasePath' , 'SearchInit' , 'PaginateInit',
'SchedulesList',
'Rest' , 'ProcessErrors', 'managementJobsListObject', '$rootScope',
'transitionTo', 'Stream',
function( Wait, $location, $compile, CreateDialog, GenerateList,
GetBasePath, SearchInit, PaginateInit,
SchedulesList,
Rest, ProcessErrors, managementJobsListObject, $rootScope,
transitionTo, Stream) {
var scope = $rootScope.$new(),
parent_scope = scope,
defaultUrl = GetBasePath('system_job_templates'),
list = managementJobsListObject,
view = GenerateList, e;
scope.cleanupJob = true;
view.inject( list, {
mode: 'edit',
scope: scope,
showSearch: true
});
SearchInit({
scope: scope,
set: 'configure_jobs',
list: list,
url: defaultUrl
});
PaginateInit({
scope: scope,
list: list,
url: defaultUrl
});
scope.search(list.iterator);
scope.showActivity = function () {
Stream({ scope: scope });
};
// Cancel
scope.cancelConfigure = function () {
try {
$('#configure-tower-dialog').dialog('close');
$("#configure-save-button").remove();
}
catch(e) {
//ignore
}
if (scope.searchCleanup) {
scope.searchCleanup();
}
// if (!Empty(parent_scope) && parent_scope.restoreSearch) {
// parent_scope.restoreSearch();
// }
else {
Wait('stop');
}
};
scope.submitCleanupJob = function(id, name){
defaultUrl = GetBasePath('system_job_templates')+id+'/launch/';
CreateDialog({
id: 'prompt-for-days-facts',
title: name,
scope: scope,
width: 500,
height: 470,
minWidth: 200,
callback: 'PromptForDaysFacts',
onOpen: function(){
scope.keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
scope.granularity_keep_unit_choices = [{
"label" : "Days",
"value" : "d"
},
{
"label": "Weeks",
"value" : "w"
},
{
"label" : "Years",
"value" : "y"
}];
e = angular.element(document.getElementById('prompt_for_days_facts_form'));
scope.prompt_for_days_facts_form.keep_amount.$setViewValue(30);
scope.prompt_for_days_facts_form.granularity_keep_amount.$setViewValue(1);
$compile(e)(scope);
scope.keep_unit = scope.keep_unit_choices[0];
scope.granularity_keep_unit = scope.granularity_keep_unit_choices[1];
// this is a work-around for getting awMax to work (without
// clearing out the form)
scope.$watch('keep_amount', function(newVal) {
if (!newVal && newVal !== 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (isNaN(newVal)) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal < 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal > 9999) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else {
$('#prompt-for-days-facts-launch').prop("disabled", false);
}
});
scope.$watch('granularity_keep_amount', function(newVal2) {
if (!newVal2 && newVal2 !== 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (isNaN(newVal2)) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal2 < 0) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else if (newVal2 > 9999) {
$('#prompt-for-days-facts-launch').prop("disabled", true);
} else {
$('#prompt-for-days-facts-launch').prop("disabled", false);
}
});
},
buttons: [{
"label": "Cancel",
"onClick": function() {
$(this).dialog('close');
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "prompt-for-days-facts-cancel"
},{
"label": "Launch",
"onClick": function() {
var extra_vars = {
"older_than": scope.keep_amount+scope.keep_unit.value,
"granularity": scope.granularity_keep_amount+scope.granularity_keep_unit.value
},
data = {};
data.extra_vars = JSON.stringify(extra_vars);
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function() {
Wait('stop');
$("#prompt-for-days-facts").dialog("close");
$("#configure-tower-dialog").dialog('close');
$location.path('/jobs/');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed updating job ' + scope.job_template_id + ' with variables. POST returned: ' + status });
});
},
"icon": "fa-rocket",
"class": "btn btn-primary",
"id": "prompt-for-days-facts-launch"
}]
});
if (scope.removePromptForDays) {
scope.removePromptForDays();
}
scope.removePromptForDays = scope.$on('PromptForDaysFacts', function() {
// $('#configure-tower-dialog').dialog('close');
$('#prompt-for-days-facts').show();
$('#prompt-for-days-facts').dialog('open');
Wait('stop');
});
};
scope.submitJob = function (id, name) {
Wait('start');
if(this.configure_job.job_type === "cleanup_facts"){
scope.submitCleanupJob(id, name);
}
else {
defaultUrl = GetBasePath('system_job_templates')+id+'/launch/';
CreateDialog({
id: 'prompt-for-days' ,
title: name,
scope: scope,
width: 500,
height: 300,
minWidth: 200,
callback: 'PromptForDays',
onOpen: function(){
e = angular.element(document.getElementById('prompt_for_days_form'));
scope.prompt_for_days_form.days_to_keep.$setViewValue(30);
$compile(e)(scope);
// this is a work-around for getting awMax to work (without
// clearing out the form)
scope.$watch('days_to_keep', function(newVal) { // oldVal, scope) { // unused params get caught by jshint
if (!newVal && newVal !== 0) {
$('#prompt-for-days-launch').prop("disabled", true);
} else if (isNaN(newVal)) {
$('#prompt-for-days-launch').prop("disabled", true);
} else if (newVal < 0) {
$('#prompt-for-days-launch').prop("disabled", true);
} else if (newVal > 9999) {
$('#prompt-for-days-launch').prop("disabled", true);
} else {
$('#prompt-for-days-launch').prop("disabled", false);
}
});
},
buttons: [{
"label": "Cancel",
"onClick": function() {
$(this).dialog('close');
},
"icon": "fa-times",
"class": "btn btn-default",
"id": "prompt-for-days-cancel"
},{
"label": "Launch",
"onClick": function() {
var extra_vars = {"days": scope.days_to_keep },
data = {};
data.extra_vars = JSON.stringify(extra_vars);
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function() {
Wait('stop');
$("#prompt-for-days").dialog("close");
// $("#configure-tower-dialog").dialog('close');
$location.path('/jobs/');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Failed updating job ' + scope.job_template_id + ' with variables. POST returned: ' + status });
});
},
"icon": "fa-rocket",
"class": "btn btn-primary",
"id": "prompt-for-days-launch"
}]
});
if (scope.removePromptForDays) {
scope.removePromptForDays();
}
scope.removePromptForDays = scope.$on('PromptForDays', function() {
// $('#configure-tower-dialog').dialog('close');
$('#prompt-for-days').show();
$('#prompt-for-days').dialog('open');
Wait('stop');
});
}
};
scope.configureSchedule = function() {
transitionTo('managementJobsSchedule', {
management_job: this.configure_job
});
};
parent_scope.refreshJobs = function(){
scope.search(SchedulesList.iterator);
};
}
];

View File

@@ -0,0 +1,8 @@
<breadcrumbs>
<breadcrumb path="/setup" title="Setup"></breadcrumb>
<breadcrumb path="/management_jobs" title="Management Jobs" current='true'></breadcrumb>
</breadcrumbs>
<div class="tab-pane" id="management_jobs">
<div ng-cloak id="htmlTemplate"></div>
</div>

View File

@@ -0,0 +1,17 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'managementJobsList',
route: '/management_jobs',
templateUrl: '/static/js/management-jobs/list/list.partial.html',
controller: 'listController',
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}]
}
};

View File

@@ -0,0 +1,17 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import route from './list.route';
import controller from './list.controller';
export default
angular.module('managementJobsList', [])
.controller('listController', controller)
.config(['$routeProvider', function($routeProvider) {
var url = route.route;
delete route.route;
$routeProvider.when(url, route);
}]);

View File

@@ -0,0 +1,16 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import managementJobsList from './list/main';
import managementJobsSchedule from './schedule/main';
import list from './management-jobs.list';
export default
angular.module('managementJobs', [
managementJobsList.name,
managementJobsSchedule.name
])
.factory('managementJobsListObject', list);

View File

@@ -4,23 +4,15 @@
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
export default function(){
return {
export default
angular.module('ConfigureTowerJobsListDefinition', [])
.value('ConfigureTowerJobsList', {
name: 'configure_jobs', name: 'configure_jobs',
iterator: 'configure_job', iterator: 'configure_job',
selectTitle: 'Configure Tower Jobs',
editTitle: 'Configure Tower Jobs',
index: false, index: false,
hover: true, hover: true,
fields: { fields: {
name: { name: {
// key: true,
label: 'Name', label: 'Name',
columnClass: 'col-sm-4 col-xs-4' columnClass: 'col-sm-4 col-xs-4'
}, },
@@ -29,6 +21,15 @@ export default
columnClass: 'col-sm-6 col-xs-6 hidden-sm hidden-xs' columnClass: 'col-sm-6 col-xs-6 hidden-sm hidden-xs'
} }
}, },
actions: {
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
icon: "icon-comments-alt",
mode: 'edit',
awFeature: 'activity_streams'
}
},
fieldActions: { fieldActions: {
submit: { submit: {
label: 'Launch', label: 'Launch',
@@ -40,16 +41,10 @@ export default
schedule: { schedule: {
label: 'Schedule', label: 'Schedule',
mode: 'all', mode: 'all',
ngClick: 'configureSchedule(configure_job.id, configure_job.name)', // '#/job_templates/{{ configure_job.id }}/schedules', ngClick: 'configureSchedule()',
awToolTip: 'Schedule future job template runs', awToolTip: 'Schedule future job template runs',
dataPlacement: 'top', dataPlacement: 'top',
} }
// delete: {
// label: 'Delete Schedule',
// mode: 'all',
// ngClick: 'deleteSystemSchedule(configure_job.id)', // '#/job_templates/{{ configure_job.id }}/schedules',
// awToolTip: 'Delete the schedule ',
// dataPlacement: 'top'
// }
} }
}); };
}

View File

@@ -0,0 +1,17 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import route from './schedule.route';
import controller from './schedule.controller';
export default
angular.module('managementJobsSchedule', [])
.controller('scheduleController', controller)
.config(['$routeProvider', function($routeProvider) {
var url = route.route;
delete route.route;
$routeProvider.when(url, route);
}]);

View File

@@ -0,0 +1,93 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name controllers.function:Schedules
* @description This controller's for schedules
*/
export default [
'$scope', '$location', '$routeParams', 'SchedulesList', 'Rest',
'ProcessErrors', 'GetBasePath', 'Wait','LoadSchedulesScope', 'GetChoices',
'Stream', 'management_job', '$rootScope',
function($scope, $location, $routeParams, SchedulesList, Rest,
ProcessErrors, GetBasePath, Wait, LoadSchedulesScope, GetChoices,
Stream, management_job, $rootScope) {
var base, id, url, parentObject;
$scope.management_job = management_job;
base = $location.path().replace(/^\//, '').split('/')[0];
// GetBasePath('management_job') must map to 'system_job_templates'
// to match the api syntax
$rootScope.defaultUrls.management_jobs = 'api/v1/system_job_templates/';
if ($scope.removePostRefresh) {
$scope.removePostRefresh();
}
$scope.removePostRefresh = $scope.$on('PostRefresh', function() {
var list = $scope.schedules;
list.forEach(function(element, idx) {
list[idx].play_tip = (element.enabled) ? 'Schedule is Active.'+
' Click to temporarily stop.' : 'Schedule is temporarily '+
'stopped. Click to activate.';
});
});
if ($scope.removeParentLoaded) {
$scope.removeParentLoaded();
}
$scope.removeParentLoaded = $scope.$on('ParentLoaded', function() {
url += "schedules/";
SchedulesList.well = true;
LoadSchedulesScope({
parent_scope: $scope,
scope: $scope,
list: SchedulesList,
id: 'management_jobs_schedule',
url: url,
pageSize: 20
});
});
if ($scope.removeChoicesReady) {
$scope.removeChocesReady();
}
$scope.removeChoicesReady = $scope.$on('choicesReady', function() {
// Load the parent object
id = $routeParams.management_job;
url = GetBasePath('system_job_templates') + id + '/';
Rest.setUrl(url);
Rest.get()
.success(function(data) {
parentObject = data;
$scope.$emit('ParentLoaded');
})
.error(function(data, status) {
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + ' failed. GET returned: ' + status });
});
});
$scope.refreshJobs = function() {
$scope.search(SchedulesList.iterator);
};
$scope.showActivity = function () {
Stream({ scope: $scope });
};
Wait('start');
GetChoices({
scope: $scope,
url: GetBasePath('system_jobs'),
field: 'type',
variable: 'type_choices',
callback: 'choicesReady'
});
}
];

View File

@@ -0,0 +1,12 @@
<breadcrumbs>
<breadcrumb path="/setup" title="Setup"></breadcrumb>
<breadcrumb path="/management_jobs" title="{{management_job.name}}"></breadcrumb>
<breadcrumb path="/management_jobs/{{management_job.id}}" title="Schedules" current='true'></breadcrumb>
</breadcrumbs>
<div class="tab-pane" id="management_jobs_schedule">
<div ng-cloak id="htmlTemplate"></div>
</div>
<div ng-include="'/static/partials/logviewer.html'"></div>
<div ng-include="'/static/partials/schedule_dialog.html'"></div>

View File

@@ -0,0 +1,44 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'managementJobsSchedule',
route: '/management_jobs/:management_job/schedules',
templateUrl: '/static/js/management-jobs/schedule/schedule.partial.html',
controller: 'scheduleController',
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}],
management_job:
[ '$route',
'$q',
'Rest',
'GetBasePath',
'ProcessErrors',
function($route, $q, rest, getBasePath, ProcessErrors) {
if ($route.current.hasModelKey('management_job')) {
return $q.when($route.current.params.model.management_job);
}
var managementJobId = $route.current.params.management_job;
var url = getBasePath('system_job_templates') + managementJobId + '/';
rest.setUrl(url);
return rest.get()
.then(function(data) {
return data.data;
}).catch(function (response) {
ProcessErrors(null, response.data, response.status, null, {
hdr: 'Error!',
msg: 'Failed to get inventory script info. GET returned status: ' +
response.status
});
});
}
]
}
};

View File

@@ -1,31 +0,0 @@
<div id="configure-jobs" ><div>
<div class="tab-pane" id="configure-schedules-tab">
<div id="configure-schedules-overlay"></div>
<div id="configure-schedules-list"></div>
<div id="configure-schedules-form-container">
<div id="configure-schedules-title">
<h4 ng-bind="schedulesTitle"></h4>
<button type="button" class="close pull-right" ng-click="cancelScheduleForm()">x</button>
</div>
<div id="configure-schedules-form-container-body">
<div id="configure-schedules-form"></div>
<div id="configure-schedules-detail"></div>
</div>
<div id="configure-schedules-buttons" >
<a id="configure-schedules-flip-link" ng-show="formShowing" ng-click="showScheduleDetail()" href=""><i class="fa fa-search-plus"></i> View Details</a>
<a id="configure-schedules-flip-link" ng-show="!formShowing" ng-click="showScheduleDetail()" href=""><i class="fa fa-arrow-circle-left"></i> Back to options</a>
<button type="button" class="btn btn-default btn-sm" id="configure-schedule-delete-button" ng-show="mode==='edit'" ng-click="deleteSystemSchedule($event)"><i class="fa fa-trash-o"></i> Delete</button>
<button type="button" class="btn btn-default btn-sm" id="configure-reset-button" ng-click="cancelScheduleForm()"><i class="fa fa-times"></i> Cancel</button>
<button type="button" class="btn btn-primary btn-sm" id="configure-save-button" ng-click="saveScheduleForm()"><i class="fa fa-check"></i> Save</button>
</div>
</div>
</div>
<!-- </div> -->
<div id="prompt-for-days" style="display:none">
<form name="prompt_for_days_form" id="prompt_for_days_form">
How many days of data would you like to <b>keep</b>? <br>
<input type="number" min="0" id="days_to_keep" name="days_to_keep" value="30" ng-required="true" class="form-control ng-pristine ng-invalid-required ng-invalid" style="margin-top:10px;">
<div class="error" ng-show="prompt_for_days_form.days_to_keep.$dirty && copy_form.new_copy_name.$error.required">Please enter the number of days you would like to keep this data.</div></input>
</form>
</div>

View File

@@ -4,7 +4,6 @@ import icon from '../shared/icon/main';
export default export default
angular.module('setupMenu', angular.module('setupMenu',
[ 'AboutAnsibleHelpModal', [ 'AboutAnsibleHelpModal',
'ConfigureTowerHelper',
icon.name icon.name
]) ])
.config(['$routeProvider', function($routeProvider) { .config(['$routeProvider', function($routeProvider) {

View File

@@ -53,19 +53,16 @@
</p> </p>
</div> </div>
</a> </a>
<button class="SetupItem SetupItem--button SetupItem--aside HoverIcon Media" ng-click="showManagementJobsModal()" ng-if="user_is_superuser"> <a link-to="managementJobsList" class="SetupItem SetupItem--aside HoverIcon Media">
<div class="SetupItem-firefoxFlexButtonFix"> <i class="HoverIcon-icon HoverIcon-icon--opacity HoverIcon-icon--color Media-figure SetupItem-icon SetupItem-icon--aside" ng-if="user_is_superuser">
<i class="HoverIcon-icon HoverIcon-icon--opacity HoverIcon-icon--color Media-figure SetupItem-icon SetupItem-icon--aside "> <aw-icon name="ManagementJobs"></aw-icon>
<aw-icon name="ManagementJobs"></aw-icon> </i>
</i> <div class="Media-block">
<div class="Media-block"> <h4 class="SetupItem-title SetupItem-title--aside">Management Jobs</h4>
<h4 class="SetupItem-title SetupItem-title--aside">Management Jobs</h4> <p class="SetupItem-description SetupItem-description--aside">
<p class="SetupItem-description SetupItem-description--aside"> Manage the cleanup of old job history, activity streams, data marked for deletion, and system tracking info.
Manage the cleanup of old job history, activity streams, data marked for deletion, and system tracking info.
</p>
</div>
</div> </div>
</button> </a>
<a link-to="inventoryScriptsList" class="SetupItem SetupItem--aside HoverIcon Media"> <a link-to="inventoryScriptsList" class="SetupItem SetupItem--aside HoverIcon Media">
<i class="HoverIcon-icon HoverIcon-icon--opacity HoverIcon-icon--color Media-figure SetupItem-icon SetupItem-icon--aside "> <i class="HoverIcon-icon HoverIcon-icon--opacity HoverIcon-icon--color Media-figure SetupItem-icon SetupItem-icon--aside ">
<aw-icon name="InventoryScripts"></aw-icon> <aw-icon name="InventoryScripts"></aw-icon>

View File

@@ -2,20 +2,11 @@ export default
[ '$scope', [ '$scope',
'$rootScope', '$rootScope',
'AboutAnsibleHelp', 'AboutAnsibleHelp',
'ConfigureTower',
function( function(
$scope, $scope,
$rootScope, $rootScope,
showAboutModal, showAboutModal
configureTower
) { ) {
$scope.showAboutModal = showAboutModal; $scope.showAboutModal = showAboutModal;
$scope.showManagementJobsModal =
configureTower.bind(null,
{ scope: $rootScope,
parent_scope: $rootScope
});
} }
]; ];

View File

@@ -155,30 +155,6 @@
<div id="about-modal-dialog" style="display: none;" ng-include=" '{{ STATIC_URL }}assets/cowsay-about.html ' "></div> <div id="about-modal-dialog" style="display: none;" ng-include=" '{{ STATIC_URL }}assets/cowsay-about.html ' "></div>
<div id='configure-tower-dialog' style="display:none" >
<div id="configure-jobs" ></div>
<div class="tab-pane" id="configure-schedules-tab">
<div id="configure-schedules-overlay"></div>
<div id="configure-schedules-list"></div>
<div id="configure-schedules-form-container">
<div id="configure-schedules-title">
<h4 ng-bind="schedulesTitle"></h4>
<button type="button" class="close pull-right" ng-click="cancelScheduleForm()">x</button>
</div>
<div id="configure-schedules-form-container-body">
<div id="configure-schedules-form"></div>
<div id="configure-schedules-detail"></div>
</div>
<div id="configure-schedules-buttons" >
<a id="configure-schedules-flip-link" ng-show="formShowing" ng-click="showScheduleDetail()" href=""><i class="fa fa-search-plus"></i> View Details</a>
<a id="configure-schedules-flip-link" ng-show="!formShowing" ng-click="showScheduleDetail()" href=""><i class="fa fa-arrow-circle-left"></i> Back to options</a>
<button type="button" class="btn btn-default btn-sm" id="configure-schedule-delete-button" ng-show="mode==='edit'" ng-click="deleteSystemSchedule($event)"><i class="fa fa-trash-o"></i> Delete</button>
<button type="button" class="btn btn-default btn-sm" id="configure-cancel-button" ng-click="cancelScheduleForm()"><i class="fa fa-times"></i> Cancel</button>
<!-- <button type="button" class="btn btn-primary btn-sm" id="configure-save-button" ng-click="saveScheduleForm()"><i class="fa fa-check"></i> Save</button> -->
</div>
</div>
</div>
</div>
<div id="prompt-for-days" style="display:none"> <div id="prompt-for-days" style="display:none">
<form name="prompt_for_days_form" id="prompt_for_days_form"> <form name="prompt_for_days_form" id="prompt_for_days_form">
Set how many days of data should be retained. <br> Set how many days of data should be retained. <br>