mirror of
https://github.com/ansible/awx.git
synced 2026-05-17 22:37:41 -02:30
Latest inventory group dialog changes for schedules integration.
This commit is contained in:
@@ -15,19 +15,6 @@ angular.module('GroupFormDefinition', [])
|
|||||||
cancelButton: false,
|
cancelButton: false,
|
||||||
name: 'group',
|
name: 'group',
|
||||||
well: false,
|
well: false,
|
||||||
formLabelSize: 'col-lg-3',
|
|
||||||
formFieldSize: 'col-lg-9',
|
|
||||||
|
|
||||||
tabs: [{
|
|
||||||
name: 'properties',
|
|
||||||
label: 'Properties'
|
|
||||||
}, {
|
|
||||||
name: 'source',
|
|
||||||
label: 'Source'
|
|
||||||
},{
|
|
||||||
name: 'schedules',
|
|
||||||
label: 'Schedules'
|
|
||||||
}],
|
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
name: {
|
name: {
|
||||||
@@ -64,143 +51,10 @@ angular.module('GroupFormDefinition', [])
|
|||||||
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
|
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
|
||||||
dataContainer: 'body',
|
dataContainer: 'body',
|
||||||
tab: 'properties'
|
tab: 'properties'
|
||||||
},
|
|
||||||
source: {
|
|
||||||
label: 'Source',
|
|
||||||
type: 'select',
|
|
||||||
ngOptions: 'source.label for source in source_type_options',
|
|
||||||
ngChange: 'sourceChange()',
|
|
||||||
addRequired: false,
|
|
||||||
editRequired: false,
|
|
||||||
//'default': { label: 'Manual', value: '' },
|
|
||||||
tab: 'source'
|
|
||||||
},
|
|
||||||
source_path: {
|
|
||||||
label: 'Script Path',
|
|
||||||
ngShow: "source && source.value == 'file'",
|
|
||||||
type: 'text',
|
|
||||||
awRequiredWhen: {
|
|
||||||
variable: "sourcePathRequired",
|
|
||||||
init: "false"
|
|
||||||
},
|
|
||||||
tab: 'source'
|
|
||||||
},
|
|
||||||
credential: {
|
|
||||||
label: 'Cloud Credential',
|
|
||||||
type: 'lookup',
|
|
||||||
ngShow: "source && source.value !== ''",
|
|
||||||
sourceModel: 'credential',
|
|
||||||
sourceField: 'name',
|
|
||||||
ngClick: 'lookUpCredential()',
|
|
||||||
addRequired: false,
|
|
||||||
editRequired: false,
|
|
||||||
tab: 'source'
|
|
||||||
},
|
|
||||||
source_regions: {
|
|
||||||
label: 'Regions',
|
|
||||||
type: 'text',
|
|
||||||
ngShow: "source && (source.value == 'rax' || source.value == 'ec2')",
|
|
||||||
addRequired: false,
|
|
||||||
editRequired: false,
|
|
||||||
awMultiselect: 'source_region_choices',
|
|
||||||
dataTitle: 'Source Regions',
|
|
||||||
dataPlacement: 'right',
|
|
||||||
awPopOver: "<p>Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
|
|
||||||
"or choose <em>All</em> to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
|
|
||||||
"</p>",
|
|
||||||
dataContainer: 'body',
|
|
||||||
tab: 'source'
|
|
||||||
},
|
|
||||||
source_vars: {
|
|
||||||
label: 'Source Variables',
|
|
||||||
ngShow: "source && (source.value == 'file' || source.value == 'ec2')",
|
|
||||||
type: 'textarea',
|
|
||||||
addRequired: false,
|
|
||||||
editRequird: false,
|
|
||||||
rows: 6,
|
|
||||||
'default': '---',
|
|
||||||
parseTypeName: 'envParseType',
|
|
||||||
dataTitle: 'Source Variables',
|
|
||||||
dataPlacement: 'right',
|
|
||||||
awPopOver: "<p>Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
|
|
||||||
"<a href=\"https://github.com/ansible/ansible/blob/devel/plugins/inventory/ec2.ini\" target=\"_blank\">" +
|
|
||||||
"view ec2.ini in the Ansible github repo.</a></p>" +
|
|
||||||
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
|
||||||
"JSON:<br />\n" +
|
|
||||||
"<blockquote>{<br />\"somevar\": \"somevalue\",<br />\"password\": \"magic\"<br /> }</blockquote>\n" +
|
|
||||||
"YAML:<br />\n" +
|
|
||||||
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
|
|
||||||
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
|
|
||||||
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
|
|
||||||
dataContainer: 'body',
|
|
||||||
tab: 'source'
|
|
||||||
},
|
|
||||||
checkbox_group: {
|
|
||||||
label: 'Update Options',
|
|
||||||
type: 'checkbox_group',
|
|
||||||
ngShow: "source && (source.value !== '' && source.value !== null)",
|
|
||||||
tab: 'source',
|
|
||||||
|
|
||||||
fields: [{
|
|
||||||
name: 'overwrite',
|
|
||||||
label: 'Overwrite',
|
|
||||||
type: 'checkbox',
|
|
||||||
ngShow: "source.value !== '' && source.value !== null",
|
|
||||||
addRequired: false,
|
|
||||||
editRequired: false,
|
|
||||||
awPopOver: '<p>When checked all child groups and hosts not found on the remote source will be deleted from ' +
|
|
||||||
'the local inventory.</p><p>Unchecked any local child hosts and groups not found on the external source will ' +
|
|
||||||
'remain untouched by the inventory update process.</p>',
|
|
||||||
dataTitle: 'Overwrite',
|
|
||||||
dataContainer: 'body',
|
|
||||||
dataPlacement: 'right',
|
|
||||||
labelClass: 'checkbox-options'
|
|
||||||
}, {
|
|
||||||
name: 'overwrite_vars',
|
|
||||||
label: 'Overwrite Variables',
|
|
||||||
type: 'checkbox',
|
|
||||||
ngShow: "source.value !== '' && source.value !== null",
|
|
||||||
addRequired: false,
|
|
||||||
editRequired: false,
|
|
||||||
awPopOver: '<p>If checked, all variables for child groups and hosts will be removed and replaced by those ' +
|
|
||||||
'found on the external source.</p><p>When not checked a merge will be performed, combining local variables with ' +
|
|
||||||
'those found on the external source.</p>',
|
|
||||||
dataTitle: 'Overwrite Variables',
|
|
||||||
dataContainer: 'body',
|
|
||||||
dataPlacement: 'right',
|
|
||||||
labelClass: 'checkbox-options'
|
|
||||||
}, {
|
|
||||||
name: 'update_on_launch',
|
|
||||||
label: 'Update on Launch',
|
|
||||||
type: 'checkbox',
|
|
||||||
ngShow: "source.value !== '' && source.value !== null",
|
|
||||||
addRequired: false,
|
|
||||||
editRequired: false,
|
|
||||||
awPopOver: '<p>Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
|
|
||||||
'executing job tasks.</p>',
|
|
||||||
dataTitle: 'Update on Launch',
|
|
||||||
dataContainer: 'body',
|
|
||||||
dataPlacement: 'right',
|
|
||||||
labelClass: 'checkbox-options'
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
buttons: {
|
buttons: { },
|
||||||
/*
|
|
||||||
labelClass: 'col-lg-3',
|
|
||||||
controlClass: 'col-lg-5',
|
|
||||||
|
|
||||||
save: {
|
|
||||||
ngClick: 'formSave()',
|
|
||||||
ngDisabled: true
|
|
||||||
},
|
|
||||||
reset: {
|
|
||||||
ngClick: 'formReset()',
|
|
||||||
ngDisabled: true //Disabled when $pristine
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
|
|
||||||
related: { }
|
related: { }
|
||||||
|
|
||||||
|
|||||||
140
awx/ui/static/js/forms/Source.js
Normal file
140
awx/ui/static/js/forms/Source.js
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2014 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* Groups.js
|
||||||
|
* Form definition for Group model
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
angular.module('SourceFormDefinition', [])
|
||||||
|
.value('SourceForm', {
|
||||||
|
|
||||||
|
addTitle: 'Create Source',
|
||||||
|
editTitle: 'Edit Source',
|
||||||
|
showTitle: false,
|
||||||
|
cancelButton: false,
|
||||||
|
name: 'source',
|
||||||
|
well: false,
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
source: {
|
||||||
|
label: 'Source',
|
||||||
|
type: 'select',
|
||||||
|
ngOptions: 'source.label for source in source_type_options',
|
||||||
|
ngChange: 'sourceChange()',
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false
|
||||||
|
},
|
||||||
|
source_path: {
|
||||||
|
label: 'Script Path',
|
||||||
|
ngShow: "source && source.value == 'file'",
|
||||||
|
type: 'text',
|
||||||
|
awRequiredWhen: {
|
||||||
|
variable: "sourcePathRequired",
|
||||||
|
init: "false"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
credential: {
|
||||||
|
label: 'Cloud Credential',
|
||||||
|
type: 'lookup',
|
||||||
|
ngShow: "source && source.value !== ''",
|
||||||
|
sourceModel: 'credential',
|
||||||
|
sourceField: 'name',
|
||||||
|
ngClick: 'lookUpCredential()',
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false
|
||||||
|
},
|
||||||
|
source_regions: {
|
||||||
|
label: 'Regions',
|
||||||
|
type: 'text',
|
||||||
|
ngShow: "source && (source.value == 'rax' || source.value == 'ec2')",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awMultiselect: 'source_region_choices',
|
||||||
|
dataTitle: 'Source Regions',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
awPopOver: "<p>Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
|
||||||
|
"or choose <em>All</em> to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
|
||||||
|
"</p>",
|
||||||
|
dataContainer: 'body'
|
||||||
|
},
|
||||||
|
source_vars: {
|
||||||
|
label: 'Source Variables',
|
||||||
|
ngShow: "source && (source.value == 'file' || source.value == 'ec2')",
|
||||||
|
type: 'textarea',
|
||||||
|
addRequired: false,
|
||||||
|
editRequird: false,
|
||||||
|
rows: 6,
|
||||||
|
'default': '---',
|
||||||
|
parseTypeName: 'envParseType',
|
||||||
|
dataTitle: 'Source Variables',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
awPopOver: "<p>Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables " +
|
||||||
|
"<a href=\"https://github.com/ansible/ansible/blob/devel/plugins/inventory/ec2.ini\" target=\"_blank\">" +
|
||||||
|
"view ec2.ini in the Ansible github repo.</a></p>" +
|
||||||
|
"<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||||
|
"JSON:<br />\n" +
|
||||||
|
"<blockquote>{<br />\"somevar\": \"somevalue\",<br />\"password\": \"magic\"<br /> }</blockquote>\n" +
|
||||||
|
"YAML:<br />\n" +
|
||||||
|
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
|
||||||
|
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
|
||||||
|
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
|
||||||
|
dataContainer: 'body'
|
||||||
|
},
|
||||||
|
checkbox_group: {
|
||||||
|
label: 'Update Options',
|
||||||
|
type: 'checkbox_group',
|
||||||
|
ngShow: "source && (source.value !== '' && source.value !== null)",
|
||||||
|
|
||||||
|
fields: [{
|
||||||
|
name: 'overwrite',
|
||||||
|
label: 'Overwrite',
|
||||||
|
type: 'checkbox',
|
||||||
|
ngShow: "source.value !== '' && source.value !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPopOver: '<p>When checked all child groups and hosts not found on the remote source will be deleted from ' +
|
||||||
|
'the local inventory.</p><p>Unchecked any local child hosts and groups not found on the external source will ' +
|
||||||
|
'remain untouched by the inventory update process.</p>',
|
||||||
|
dataTitle: 'Overwrite',
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
labelClass: 'checkbox-options'
|
||||||
|
}, {
|
||||||
|
name: 'overwrite_vars',
|
||||||
|
label: 'Overwrite Variables',
|
||||||
|
type: 'checkbox',
|
||||||
|
ngShow: "source.value !== '' && source.value !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPopOver: '<p>If checked, all variables for child groups and hosts will be removed and replaced by those ' +
|
||||||
|
'found on the external source.</p><p>When not checked a merge will be performed, combining local variables with ' +
|
||||||
|
'those found on the external source.</p>',
|
||||||
|
dataTitle: 'Overwrite Variables',
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
labelClass: 'checkbox-options'
|
||||||
|
}, {
|
||||||
|
name: 'update_on_launch',
|
||||||
|
label: 'Update on Launch',
|
||||||
|
type: 'checkbox',
|
||||||
|
ngShow: "source.value !== '' && source.value !== null",
|
||||||
|
addRequired: false,
|
||||||
|
editRequired: false,
|
||||||
|
awPopOver: '<p>Each time a job runs using this inventory, refresh the inventory from the selected source before ' +
|
||||||
|
'executing job tasks.</p>',
|
||||||
|
dataTitle: 'Update on Launch',
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
labelClass: 'checkbox-options'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
buttons: {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
related: { }
|
||||||
|
|
||||||
|
});
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'GroupListDefinition', 'SearchHelper',
|
angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'GroupListDefinition', 'SearchHelper',
|
||||||
'PaginationHelpers', 'ListGenerator', 'AuthService', 'GroupsHelper', 'InventoryHelper', 'SelectionHelper',
|
'PaginationHelpers', 'ListGenerator', 'AuthService', 'GroupsHelper', 'InventoryHelper', 'SelectionHelper',
|
||||||
'JobSubmissionHelper', 'RefreshHelper', 'PromptDialog', 'CredentialsListDefinition', 'InventoryTree',
|
'JobSubmissionHelper', 'RefreshHelper', 'PromptDialog', 'CredentialsListDefinition', 'InventoryTree',
|
||||||
'InventoryStatusDefinition', 'VariablesHelper'])
|
'InventoryStatusDefinition', 'VariablesHelper', 'SchedulesListDefinition', 'SourceFormDefinition'])
|
||||||
|
|
||||||
.factory('GetSourceTypeOptions', ['Rest', 'ProcessErrors', 'GetBasePath',
|
.factory('GetSourceTypeOptions', ['Rest', 'ProcessErrors', 'GetBasePath',
|
||||||
function (Rest, ProcessErrors, GetBasePath) {
|
function (Rest, ProcessErrors, GetBasePath) {
|
||||||
@@ -197,14 +197,14 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
if (scope.source.value === 'rax') {
|
if (scope.source.value === 'rax') {
|
||||||
scope.source_region_choices = scope.rax_regions;
|
scope.source_region_choices = scope.rax_regions;
|
||||||
//$('#s2id_group_source_regions').select2('data', []);
|
//$('#s2id_group_source_regions').select2('data', []);
|
||||||
$('#s2id_group_source_regions').select2('data', [{
|
$('#s2id_source_source_regions').select2('data', [{
|
||||||
id: 'all',
|
id: 'all',
|
||||||
text: 'All'
|
text: 'All'
|
||||||
}]);
|
}]);
|
||||||
} else if (scope.source.value === 'ec2') {
|
} else if (scope.source.value === 'ec2') {
|
||||||
scope.source_region_choices = scope.ec2_regions;
|
scope.source_region_choices = scope.ec2_regions;
|
||||||
//$('#s2id_group_source_regions').select2('data', []);
|
//$('#s2id_group_source_regions').select2('data', []);
|
||||||
$('#s2id_group_source_regions').select2('data', [{
|
$('#s2id_source_source_regions').select2('data', [{
|
||||||
id: 'all',
|
id: 'all',
|
||||||
text: 'All'
|
text: 'All'
|
||||||
}]);
|
}]);
|
||||||
@@ -224,7 +224,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
callback = function(){ Wait('stop'); };
|
callback = function(){ Wait('stop'); };
|
||||||
Wait('start');
|
Wait('start');
|
||||||
ParseTypeChange({ scope: scope, variable: 'source_vars', parse_variable: form.fields.source_vars.parseTypeName,
|
ParseTypeChange({ scope: scope, variable: 'source_vars', parse_variable: form.fields.source_vars.parseTypeName,
|
||||||
field_id: 'group_source_vars', onReady: callback });
|
field_id: 'source_source_vars', onReady: callback });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,15 +530,182 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Add the list of schedules to the Group Edit modal
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.factory('ScheduleList', ['ScheduleEdit', 'SchedulesList', 'GenerateList', 'SearchInit', 'PaginateInit', 'Rest', 'PageRangeSetup',
|
||||||
|
'Wait', 'ProcessErrors', 'Find',
|
||||||
|
function(ScheduleEdit, SchedulesList, GenerateList, SearchInit, PaginateInit, Rest, PageRangeSetup, Wait, ProcessErrors, Find) {
|
||||||
|
return function(params) {
|
||||||
|
var parent_scope = params.scope,
|
||||||
|
scope, url, list;
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
$('#schedules-list').hide().empty();
|
||||||
|
$('#schedules-form').hide().empty();
|
||||||
|
$('.tooltip').each(function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
$('.popover').each(function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add schedules list
|
||||||
|
list = angular.copy(SchedulesList);
|
||||||
|
delete list.fields.dtend;
|
||||||
|
delete list.actions.stream;
|
||||||
|
scope = GenerateList.inject(list, {
|
||||||
|
mode: 'edit',
|
||||||
|
id: 'schedules-list',
|
||||||
|
breadCrumbs: false,
|
||||||
|
searchSize: 'col-lg-5 col-md-5 col-sm-6 col-xs-6'
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#schedules-list').show();
|
||||||
|
|
||||||
|
// Change later to use GetBasePath(base)
|
||||||
|
url = '/static/sample/data/schedules/inventory/data.json';
|
||||||
|
SearchInit({
|
||||||
|
scope: scope,
|
||||||
|
set: 'schedules',
|
||||||
|
list: SchedulesList,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: scope,
|
||||||
|
list: SchedulesList,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success(function(data) {
|
||||||
|
var i, modifier;
|
||||||
|
PageRangeSetup({
|
||||||
|
scope: scope,
|
||||||
|
count: data.count,
|
||||||
|
next: data.next,
|
||||||
|
previous: data.previous,
|
||||||
|
iterator: SchedulesList.iterator
|
||||||
|
});
|
||||||
|
scope[SchedulesList.iterator + 'Loading'] = false;
|
||||||
|
for (i = 1; i <= 3; i++) {
|
||||||
|
modifier = (i === 1) ? '' : i;
|
||||||
|
scope[SchedulesList.iterator + 'HoldInput' + modifier] = false;
|
||||||
|
}
|
||||||
|
scope.schedules = data.results;
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
Wait('stop');
|
||||||
|
scope.$emit('PostRefresh');
|
||||||
|
scope.schedules = data.results;
|
||||||
|
})
|
||||||
|
.error(function(data, status) {
|
||||||
|
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to ' + url + ' failed. GET returned: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.editSchedule = function(id) {
|
||||||
|
var schedule = Find({ list: scope[SchedulesList.name], key: 'id', val: id });
|
||||||
|
ScheduleEdit({ scope: parent_scope, schedule: schedule });
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Remove the schedule list, add the schedule widget and populate it with an rrule
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.factory('ScheduleEdit', ['SchedulerInit', 'Rest', 'Wait',
|
||||||
|
function(SchedulerInit, Rest, Wait) {
|
||||||
|
return function(params) {
|
||||||
|
var parent_scope = params.scope,
|
||||||
|
schedule = params.schedule,
|
||||||
|
scope = parent_scope.$new(),
|
||||||
|
scheduler,
|
||||||
|
target,
|
||||||
|
callback,
|
||||||
|
restore;
|
||||||
|
|
||||||
|
Wait('start');
|
||||||
|
target = $('#schedules-form');
|
||||||
|
|
||||||
|
// Clean up any lingering stuff
|
||||||
|
target.empty().hide();
|
||||||
|
$('.tooltip').each(function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
$('.popover').each(function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert the scheduler widget into the hidden div
|
||||||
|
scheduler = SchedulerInit({ scope: scope });
|
||||||
|
scheduler.inject('schedules-form', true);
|
||||||
|
scope.showRRuleDetail = false;
|
||||||
|
|
||||||
|
// display the scheduler widget
|
||||||
|
callback = function() {
|
||||||
|
Wait('stop');
|
||||||
|
target.show('slide', { direction: 'left' }, 500);
|
||||||
|
$('#group-save-button').prop('disabled', true);
|
||||||
|
scope.$apply(function() {
|
||||||
|
scheduler.setRRule(schedule.rrule);
|
||||||
|
scheduler.setName(schedule.name);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$('#schedules-list').hide({ complete: callback, duration: 300 });
|
||||||
|
|
||||||
|
restore = function() {
|
||||||
|
$('#group-save-button').prop('disabled', false);
|
||||||
|
$('#schedules-list').show('slide', { direction: 'right' }, 500);
|
||||||
|
//refresh the list
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.saveForm = function() {
|
||||||
|
var newSchedule,
|
||||||
|
url = '/static/sample/data/schedules/inventory/data.json';
|
||||||
|
if (scheduler.isValid()) {
|
||||||
|
scope.schedulerIsValid = true;
|
||||||
|
Wait('start');
|
||||||
|
newSchedule = scheduler.getValue();
|
||||||
|
schedule.name = newSchedule.name;
|
||||||
|
schedule.rrule = newSchedule.rrule;
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post(schedule)
|
||||||
|
.success(function(){
|
||||||
|
Wait('stop');
|
||||||
|
target.hide('slide', { direction: 'right' }, 500, restore);
|
||||||
|
})
|
||||||
|
.error(function(){
|
||||||
|
Wait('stop');
|
||||||
|
target.hide('slide', { direction: 'right' }, 500, restore);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope.schedulerIsValid = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.resetForm = function() {
|
||||||
|
scheduler.setRRule(schedule.rrule);
|
||||||
|
scheduler.setName(schedule.name);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
|
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
|
||||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate',
|
'Prompt', 'ProcessErrors', 'GetBasePath', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate',
|
||||||
'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'Find','WatchInventoryWindowResize',
|
'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'Find','WatchInventoryWindowResize',
|
||||||
'ParseVariableString', 'ToJSON',
|
'ParseVariableString', 'ToJSON', 'ScheduleList', 'SourceForm',
|
||||||
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
|
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
|
||||||
GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, LookUpInit, Empty, Wait,
|
GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, LookUpInit, Empty, Wait,
|
||||||
GetChoices, UpdateGroup, SourceChange, Find, WatchInventoryWindowResize,
|
GetChoices, UpdateGroup, SourceChange, Find, WatchInventoryWindowResize, ParseVariableString, ToJSON, ScheduleList,
|
||||||
ParseVariableString, ToJSON) {
|
SourceForm) {
|
||||||
|
|
||||||
return function (params) {
|
return function (params) {
|
||||||
|
|
||||||
var parent_scope = params.scope,
|
var parent_scope = params.scope,
|
||||||
@@ -547,42 +714,49 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
inventory_id = params.inventory_id,
|
inventory_id = params.inventory_id,
|
||||||
groups_reload = params.groups_reload,
|
groups_reload = params.groups_reload,
|
||||||
generator = GenerateForm,
|
generator = GenerateForm,
|
||||||
form = GroupForm,
|
|
||||||
defaultUrl = GetBasePath('groups') + group_id + '/',
|
defaultUrl = GetBasePath('groups') + group_id + '/',
|
||||||
master = {},
|
master = {},
|
||||||
choicesReady,
|
choicesReady,
|
||||||
scope, html, x, y, ww, wh, maxrows;
|
modal_scope = parent_scope.$new(),
|
||||||
|
properties_scope = parent_scope.$new(),
|
||||||
|
sources_scope = parent_scope.$new(),
|
||||||
|
x, y, ww, wh, maxrows;
|
||||||
|
|
||||||
|
generator.inject(GroupForm, { mode: 'edit', id: 'properties-tab', breadCrumbs: false, related: false, scope: properties_scope });
|
||||||
|
generator.inject(SourceForm, { mode: 'edit', id: 'sources-tab', breadCrumbs: false, related: false, scope: sources_scope });
|
||||||
|
|
||||||
html = "<div id=\"group-modal-dialog\" title=\"Group Edit\">\n" +
|
|
||||||
"<div id=\"form-container\" style=\"width: 100%;\"></div></div>\n";
|
|
||||||
$('#inventory-modal-container').empty().append(html);
|
|
||||||
scope = generator.inject(form, { mode: 'edit', id: 'form-container', breadCrumbs: false, related: false });
|
|
||||||
//generator.reset();
|
//generator.reset();
|
||||||
GetSourceTypeOptions({ scope: scope, variable: 'source_type_options' });
|
|
||||||
scope.source = form.fields.source['default'];
|
GetSourceTypeOptions({ scope: sources_scope, variable: 'source_type_options' });
|
||||||
scope.sourcePathRequired = false;
|
sources_scope.source = SourceForm.fields.source['default'];
|
||||||
scope[form.fields.source_vars.parseTypeName] = 'yaml';
|
sources_scope.sourcePathRequired = false;
|
||||||
scope.parseType = 'yaml';
|
sources_scope[SourceForm.fields.source_vars.parseTypeName] = 'yaml';
|
||||||
|
properties_scope.parseType = 'yaml';
|
||||||
|
|
||||||
function waitStop() { Wait('stop'); }
|
function waitStop() { Wait('stop'); }
|
||||||
|
|
||||||
|
// Attempt to create the largest textarea field that will fit on the window. Minimum
|
||||||
|
// height is 6 rows, so on short windows you will see vertical scrolling
|
||||||
function textareaResize(textareaID) {
|
function textareaResize(textareaID) {
|
||||||
var formHeight = $('#group_form').height(),
|
var textArea, formHeight, model, windowHeight, offset, rows;
|
||||||
windowHeight = $('#group-modal-dialog').height(),
|
textArea = $('#' + textareaID);
|
||||||
current_height, height, rows, row_height, model;
|
if (properties_scope.codeMirror) {
|
||||||
Wait('start');
|
model = textArea.attr('ng-model');
|
||||||
current_height = $('#' + textareaID).height();
|
properties_scope[model] = properties_scope.codeMirror.getValue();
|
||||||
row_height = Math.floor( current_height / $('#' + textareaID).attr('rows'));
|
properties_scope.codeMirror.destroy();
|
||||||
height = current_height + windowHeight - formHeight;
|
|
||||||
rows = Math.floor(height / row_height) - 3;
|
|
||||||
rows = (rows < 6) ? 6 : rows;
|
|
||||||
$('#' + textareaID).attr('rows', rows);
|
|
||||||
if (scope.codeMirror) {
|
|
||||||
model = $('#' + textareaID).attr('ng-model');
|
|
||||||
scope[model] = scope.codeMirror.getValue();
|
|
||||||
scope.codeMirror.destroy();
|
|
||||||
}
|
}
|
||||||
ParseTypeChange({ scope: scope, field_id: textareaID, onReady: waitStop });
|
textArea.attr('rows', 1);
|
||||||
|
formHeight = $('#group_form').height();
|
||||||
|
windowHeight = $('#group-modal-dialog').height() - 20; //leave a margin of 20px
|
||||||
|
offset = Math.floor(windowHeight - formHeight);
|
||||||
|
rows = Math.floor(offset / 24);
|
||||||
|
rows = (rows < 6) ? 6 : rows;
|
||||||
|
textArea.attr('rows', rows);
|
||||||
|
while(rows > 6 && $('#group_form').height() > $('#group-modal-dialog').height()) {
|
||||||
|
rows--;
|
||||||
|
textArea.attr('rows', rows);
|
||||||
|
}
|
||||||
|
ParseTypeChange({ scope: properties_scope, field_id: textareaID, onReady: waitStop });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set modal dimensions based on viewport width
|
// Set modal dimensions based on viewport width
|
||||||
@@ -607,20 +781,18 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
$('#group-modal-dialog').dialog({
|
$('#group-modal-dialog').dialog({
|
||||||
buttons: {
|
buttons: {
|
||||||
'Cancel': function() {
|
'Cancel': function() {
|
||||||
scope.cancelModal();
|
modal_scope.cancelModal();
|
||||||
},
|
},
|
||||||
'Save': function () {
|
'Save': function () {
|
||||||
//setTimeout(function(){
|
modal_scope.saveGroup();
|
||||||
// scope.$apply(function(){
|
|
||||||
scope.saveGroup();
|
|
||||||
// });
|
|
||||||
//});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modal: true,
|
modal: true,
|
||||||
width: x,
|
width: x,
|
||||||
height: y,
|
height: y,
|
||||||
autoOpen: false,
|
autoOpen: false,
|
||||||
|
minWidth: 440,
|
||||||
|
title: 'Edit Group',
|
||||||
create: function () {
|
create: function () {
|
||||||
$('.ui-dialog[aria-describedby="group-modal-dialog"]').find('.ui-dialog-titlebar button').empty().attr({'class': 'close'}).text('x');
|
$('.ui-dialog[aria-describedby="group-modal-dialog"]').find('.ui-dialog-titlebar button').empty().attr({'class': 'close'}).text('x');
|
||||||
$('.ui-dialog[aria-describedby="group-modal-dialog"]').find('.ui-dialog-buttonset button').each(function () {
|
$('.ui-dialog[aria-describedby="group-modal-dialog"]').find('.ui-dialog-buttonset button').each(function () {
|
||||||
@@ -651,7 +823,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
content = dialog.find('#group-modal-dialog');
|
content = dialog.find('#group-modal-dialog');
|
||||||
content.width(dialog.width() - 28);
|
content.width(dialog.width() - 28);
|
||||||
if ($('#group_tabs .active a').text() === 'Properties') {
|
if ($('#group_tabs .active a').text() === 'Properties') {
|
||||||
textareaResize('group_variables');
|
textareaResize('group_variables', properties_scope);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close: function () {
|
close: function () {
|
||||||
@@ -665,131 +837,121 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
$(this).remove();
|
$(this).remove();
|
||||||
});
|
});
|
||||||
$('#group-modal-dialog').dialog('destroy');
|
$('#group-modal-dialog').dialog('destroy');
|
||||||
$('#inventory-modal-container').empty();
|
$('#group-modal-dialog').hide();
|
||||||
scope.cancelModal();
|
modal_scope.cancelModal();
|
||||||
},
|
},
|
||||||
open: function () {
|
open: function () {
|
||||||
|
$('#group_name').focus();
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#group_tabs a[data-toggle="tab"]').on('show.bs.tab', function (e) {
|
$('#group_tabs a[data-toggle="tab"]').on('show.bs.tab', function (e) {
|
||||||
var callback = function(){
|
|
||||||
Wait('stop');
|
|
||||||
};
|
|
||||||
if ($(e.target).text() === 'Properties') {
|
if ($(e.target).text() === 'Properties') {
|
||||||
Wait('start');
|
Wait('start');
|
||||||
setTimeout(function(){ textareaResize('group_variables'); }, 300);
|
setTimeout(function(){ textareaResize('group_variables'); }, 300);
|
||||||
//ParseTypeChange({ scope: scope, field_id: 'group_variables', onReady: callback });
|
|
||||||
}
|
}
|
||||||
else if ($(e.target).text() === 'Scope') {
|
else if ($(e.target).text() === 'Source') {
|
||||||
if (scope.source && scope.source.value === 'ec2') {
|
if (sources_scope.source && sources_scope.source.value === 'ec2') {
|
||||||
Wait('start');
|
Wait('start');
|
||||||
ParseTypeChange({ scope: scope, variable: 'source_vars', parse_variable: form.fields.source_vars.parseTypeName,
|
ParseTypeChange({ scope: sources_scope, variable: 'source_vars', parse_variable: SourceForm.fields.source_vars.parseTypeName,
|
||||||
field_id: 'group_source_vars', onReady: callback });
|
field_id: 'source_source_vars', onReady: waitStop });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ($(e.target).text() === 'Schedule') {
|
||||||
|
ScheduleList({ scope: modal_scope });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (scope.groupVariablesLoadedRemove) {
|
if (modal_scope.groupVariablesLoadedRemove) {
|
||||||
scope.groupVariablesLoadedRemove();
|
modal_scope.groupVariablesLoadedRemove();
|
||||||
}
|
}
|
||||||
scope.groupVariablesLoadedRemove = scope.$on('groupVariablesLoaded', function () {
|
modal_scope.groupVariablesLoadedRemove = modal_scope.$on('groupVariablesLoaded', function () {
|
||||||
//$('#group_tabs a:first').tab('show');
|
$('#group_tabs a:first').tab('show');
|
||||||
|
|
||||||
//ParseTypeChange({ scope: scope, field_id: 'group_variables', onReady: callback });
|
|
||||||
Wait('start');
|
Wait('start');
|
||||||
$('#group-modal-dialog').dialog('open');
|
$('#group-modal-dialog').dialog('open');
|
||||||
setTimeout(function() { textareaResize('group_variables'); }, 300);
|
setTimeout(function() { textareaResize('group_variables', properties_scope); }, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
// After the group record is loaded, retrieve related data
|
// After the group record is loaded, retrieve related data
|
||||||
if (scope.groupLoadedRemove) {
|
if (modal_scope.groupLoadedRemove) {
|
||||||
scope.groupLoadedRemove();
|
modal_scope.groupLoadedRemove();
|
||||||
}
|
}
|
||||||
scope.groupLoadedRemove = scope.$on('groupLoaded', function () {
|
modal_scope.groupLoadedRemove = modal_scope.$on('groupLoaded', function () {
|
||||||
if (scope.variable_url) {
|
if (properties_scope.variable_url) {
|
||||||
// get group variables
|
// get group variables
|
||||||
Rest.setUrl(scope.variable_url);
|
Rest.setUrl(properties_scope.variable_url);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
scope.variables = ParseVariableString(data);
|
properties_scope.variables = ParseVariableString(data);
|
||||||
master.variables = scope.variables;
|
master.variables = properties_scope.variables;
|
||||||
scope.$emit('groupVariablesLoaded');
|
modal_scope.$emit('groupVariablesLoaded');
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
scope.variables = null;
|
properties_scope.variables = null;
|
||||||
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors(modal_scope, data, status, null, { hdr: 'Error!',
|
||||||
msg: 'Failed to retrieve group variables. GET returned status: ' + status });
|
msg: 'Failed to retrieve group variables. GET returned status: ' + status });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
scope.variables = "---";
|
properties_scope.variables = "---";
|
||||||
master.variables = scope.variables;
|
master.variables = properties_scope.variables;
|
||||||
scope.$emit('groupVariablesLoaded');
|
properties_scope.$emit('groupVariablesLoaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope.source_url) {
|
if (sources_scope.source_url) {
|
||||||
// get source data
|
// get source data
|
||||||
Rest.setUrl(scope.source_url);
|
Rest.setUrl(sources_scope.source_url);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
var fld, i, j, flag, found, set, opts, list;
|
var fld, i, j, flag, found, set, opts, list, form;
|
||||||
|
form = SourceForm;
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (fld === 'checkbox_group') {
|
if (fld === 'checkbox_group') {
|
||||||
for (i = 0; i < form.fields[fld].fields.length; i++) {
|
for (i = 0; i < form.fields[fld].fields.length; i++) {
|
||||||
flag = form.fields[fld].fields[i];
|
flag = form.fields[fld].fields[i];
|
||||||
if (data[flag.name] !== undefined) {
|
if (data[flag.name] !== undefined) {
|
||||||
scope[flag.name] = data[flag.name];
|
sources_scope[flag.name] = data[flag.name];
|
||||||
master[flag.name] = scope[flag.name];
|
master[flag.name] = sources_scope[flag.name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fld === 'source') {
|
if (fld === 'source') {
|
||||||
found = false;
|
found = false;
|
||||||
for (i = 0; i < scope.source_type_options.length; i++) {
|
for (i = 0; i < sources_scope.source_type_options.length; i++) {
|
||||||
if (scope.source_type_options[i].value === data.source) {
|
if (sources_scope.source_type_options[i].value === data.source) {
|
||||||
scope.source = scope.source_type_options[i];
|
sources_scope.source = sources_scope.source_type_options[i];
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found || scope.source.value === "") {
|
if (!found || sources_scope.source.value === "") {
|
||||||
scope.groupUpdateHide = true;
|
sources_scope.groupUpdateHide = true;
|
||||||
} else {
|
} else {
|
||||||
scope.groupUpdateHide = false;
|
sources_scope.groupUpdateHide = false;
|
||||||
}
|
|
||||||
master.source = scope.source;
|
|
||||||
} else if (fld === 'update_interval') {
|
|
||||||
if (data[fld] === '' || data[fld] === null || data[fld] === undefined) {
|
|
||||||
data[fld] = 0;
|
|
||||||
}
|
|
||||||
for (i = 0; i < scope.update_interval_options.length; i++) {
|
|
||||||
if (scope.update_interval_options[i].value === data[fld]) {
|
|
||||||
scope[fld] = scope.update_interval_options[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
master.source = sources_scope.source;
|
||||||
} else if (fld === 'source_vars') {
|
} else if (fld === 'source_vars') {
|
||||||
// Parse source_vars, converting to YAML.
|
// Parse source_vars, converting to YAML.
|
||||||
scope.source_vars = ParseVariableString(data.source_vars);
|
sources_scope.source_vars = ParseVariableString(data.source_vars);
|
||||||
master.source_vars = scope.variables;
|
master.source_vars = sources_scope.variables;
|
||||||
} else if (data[fld]) {
|
} else if (data[fld]) {
|
||||||
scope[fld] = data[fld];
|
sources_scope[fld] = data[fld];
|
||||||
master[fld] = scope[fld];
|
master[fld] = sources_scope[fld];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (form.fields[fld].sourceModel && data.summary_fields &&
|
if (form.fields[fld].sourceModel && data.summary_fields &&
|
||||||
data.summary_fields[form.fields[fld].sourceModel]) {
|
data.summary_fields[form.fields[fld].sourceModel]) {
|
||||||
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
sources_scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
||||||
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
||||||
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
||||||
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.sourceChange(); //set defaults that rely on source value
|
sources_scope.sourceChange(); //set defaults that rely on source value
|
||||||
|
|
||||||
if (data.source_regions) {
|
if (data.source_regions) {
|
||||||
if (data.source === 'ec2' || data.source === 'rax') {
|
if (data.source === 'ec2' || data.source === 'rax') {
|
||||||
set = (data.source === 'ec2') ? scope.ec2_regions : scope.rax_regions;
|
set = (data.source === 'ec2') ? sources_scope.ec2_regions : sources_scope.rax_regions;
|
||||||
opts = [];
|
opts = [];
|
||||||
list = data.source_regions.split(',');
|
list = data.source_regions.split(',');
|
||||||
for (i = 0; i < list.length; i++) {
|
for (i = 0; i < list.length; i++) {
|
||||||
@@ -803,7 +965,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
master.source_regions = opts;
|
master.source_regions = opts;
|
||||||
$('#s2id_group_source_regions').select2('data', opts);
|
$('#s2id_source_source_regions').select2('data', opts);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If empty, default to all
|
// If empty, default to all
|
||||||
@@ -811,58 +973,58 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
id: 'all',
|
id: 'all',
|
||||||
text: 'All'
|
text: 'All'
|
||||||
}];
|
}];
|
||||||
|
$('#s2id_source_source_regions').select2('data', master.source_regions);
|
||||||
}
|
}
|
||||||
scope.group_update_url = data.related.update;
|
sources_scope.group_update_url = data.related.update;
|
||||||
//Wait('stop');
|
//Wait('stop');
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
scope.source = "";
|
sources_scope.source = "";
|
||||||
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors(modal_scope, data, status, null, { hdr: 'Error!',
|
||||||
msg: 'Failed to retrieve inventory source. GET status: ' + status });
|
msg: 'Failed to retrieve inventory source. GET status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (scope.removeChoicesComplete) {
|
if (modal_scope.removeChoicesComplete) {
|
||||||
scope.removeChoicesComplete();
|
modal_scope.removeChoicesComplete();
|
||||||
}
|
}
|
||||||
scope.removeChoicesComplete = scope.$on('choicesCompleteGroup', function () {
|
modal_scope.removeChoicesComplete = modal_scope.$on('choicesCompleteGroup', function () {
|
||||||
// Retrieve detail record and prepopulate the form
|
// Retrieve detail record and prepopulate the form
|
||||||
Rest.setUrl(defaultUrl);
|
Rest.setUrl(defaultUrl);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
for (var fld in form.fields) {
|
for (var fld in GroupForm.fields) {
|
||||||
if (data[fld]) {
|
if (data[fld]) {
|
||||||
scope[fld] = data[fld];
|
properties_scope[fld] = data[fld];
|
||||||
master[fld] = scope[fld];
|
master[fld] = properties_scope[fld];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope.variable_url = data.related.variable_data;
|
properties_scope.variable_url = data.related.variable_data;
|
||||||
scope.source_url = data.related.inventory_source;
|
sources_scope.source_url = data.related.inventory_source;
|
||||||
//$('#form-modal').modal('show');
|
modal_scope.$emit('groupLoaded');
|
||||||
scope.$emit('groupLoaded');
|
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors(modal_scope, data, status, { hdr: 'Error!',
|
||||||
msg: 'Failed to retrieve group: ' + defaultUrl + '. GET status: ' + status });
|
msg: 'Failed to retrieve group: ' + defaultUrl + '. GET status: ' + status });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
choicesReady = 0;
|
choicesReady = 0;
|
||||||
|
|
||||||
if (scope.removeChoicesReady) {
|
if (sources_scope.removeChoicesReady) {
|
||||||
scope.removeChoicesReady();
|
sources_scope.removeChoicesReady();
|
||||||
}
|
}
|
||||||
scope.removeChoicesReady = scope.$on('choicesReadyGroup', function () {
|
sources_scope.removeChoicesReady = sources_scope.$on('choicesReadyGroup', function () {
|
||||||
choicesReady++;
|
choicesReady++;
|
||||||
if (choicesReady === 2) {
|
if (choicesReady === 2) {
|
||||||
scope.$emit('choicesCompleteGroup');
|
modal_scope.$emit('choicesCompleteGroup');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load options for source regions
|
// Load options for source regions
|
||||||
GetChoices({
|
GetChoices({
|
||||||
scope: scope,
|
scope: sources_scope,
|
||||||
url: GetBasePath('inventory_sources'),
|
url: GetBasePath('inventory_sources'),
|
||||||
field: 'source_regions',
|
field: 'source_regions',
|
||||||
variable: 'rax_regions',
|
variable: 'rax_regions',
|
||||||
@@ -871,7 +1033,7 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
});
|
});
|
||||||
|
|
||||||
GetChoices({
|
GetChoices({
|
||||||
scope: scope,
|
scope: sources_scope,
|
||||||
url: GetBasePath('inventory_sources'),
|
url: GetBasePath('inventory_sources'),
|
||||||
field: 'source_regions',
|
field: 'source_regions',
|
||||||
variable: 'ec2_regions',
|
variable: 'ec2_regions',
|
||||||
@@ -881,10 +1043,10 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
|
|
||||||
Wait('start');
|
Wait('start');
|
||||||
|
|
||||||
if (scope.removeSaveComplete) {
|
if (modal_scope.removeSaveComplete) {
|
||||||
scope.removeSaveComplete();
|
modal_scope.removeSaveComplete();
|
||||||
}
|
}
|
||||||
scope.removeSaveComplete = scope.$on('SaveComplete', function (e, error) {
|
modal_scope.removeSaveComplete = modal_scope.$on('SaveComplete', function (e, error) {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
// Update the view with any changes
|
// Update the view with any changes
|
||||||
if (groups_reload) {
|
if (groups_reload) {
|
||||||
@@ -892,13 +1054,13 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
scope: parent_scope,
|
scope: parent_scope,
|
||||||
group_id: group_id,
|
group_id: group_id,
|
||||||
properties: {
|
properties: {
|
||||||
name: scope.name,
|
name: properties_scope.name,
|
||||||
description: scope.description,
|
description: properties_scope.description,
|
||||||
has_inventory_sources: (scope.source && scope.source.value) ? true : false,
|
has_inventory_sources: (sources_scope.source && sources_scope.source.value) ? true : false,
|
||||||
source: (scope.source && scope.source.value) ? scope.source.value : ''
|
source: (sources_scope.source && sources_scope.source.value) ? sources_scope.source.value : ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (scope.home_groups) {
|
} else if (parent_scope.home_groups) {
|
||||||
// When home.groups controller is calling, update the groups array
|
// When home.groups controller is calling, update the groups array
|
||||||
var g = Find({
|
var g = Find({
|
||||||
list: parent_scope.home_groups,
|
list: parent_scope.home_groups,
|
||||||
@@ -906,18 +1068,16 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
val: group_id
|
val: group_id
|
||||||
});
|
});
|
||||||
if (g) {
|
if (g) {
|
||||||
g.name = scope.name;
|
g.name = properties_scope.name;
|
||||||
g.description = scope.description;
|
g.description = properties_scope.description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clean up
|
//Clean up
|
||||||
if (scope.searchCleanUp) {
|
if (modal_scope.searchCleanUp) {
|
||||||
scope.searchCleanup();
|
modal_scope.searchCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.formModalActionDisabled = false;
|
|
||||||
|
|
||||||
$('#group-modal-dialog').dialog('close');
|
$('#group-modal-dialog').dialog('close');
|
||||||
|
|
||||||
// Change the selected group
|
// Change the selected group
|
||||||
@@ -930,10 +1090,10 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (scope.removeFormSaveSuccess) {
|
if (modal_scope.removeFormSaveSuccess) {
|
||||||
scope.removeFormSaveSuccess();
|
modal_scope.removeFormSaveSuccess();
|
||||||
}
|
}
|
||||||
scope.removeFormSaveSuccess = scope.$on('formSaveSuccess', function () {
|
modal_scope.removeFormSaveSuccess = modal_scope.$on('formSaveSuccess', function () {
|
||||||
|
|
||||||
// Source data gets stored separately from the group. Validate and store Source
|
// Source data gets stored separately from the group. Validate and store Source
|
||||||
// related fields, then call SaveComplete to wrap things up.
|
// related fields, then call SaveComplete to wrap things up.
|
||||||
@@ -942,65 +1102,67 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
regions, r, i,
|
regions, r, i,
|
||||||
data = {
|
data = {
|
||||||
group: group_id,
|
group: group_id,
|
||||||
source: ((scope.source && scope.source.value) ? scope.source.value : ''),
|
source: ((sources_scope.source && sources_scope.source.value) ? sources_scope.source.value : ''),
|
||||||
source_path: scope.source_path,
|
source_path: sources_scope.source_path,
|
||||||
credential: scope.credential,
|
credential: sources_scope.credential,
|
||||||
overwrite: scope.overwrite,
|
overwrite: sources_scope.overwrite,
|
||||||
overwrite_vars: scope.overwrite_vars,
|
overwrite_vars: sources_scope.overwrite_vars,
|
||||||
update_on_launch: scope.update_on_launch
|
update_on_launch: sources_scope.update_on_launch
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a string out of selected list of regions
|
// Create a string out of selected list of regions
|
||||||
regions = $('#s2id_group_source_regions').select2("data");
|
regions = $('#s2id_source_source_regions').select2("data");
|
||||||
r = [];
|
r = [];
|
||||||
for (i = 0; i < regions.length; i++) {
|
for (i = 0; i < regions.length; i++) {
|
||||||
r.push(regions[i].id);
|
r.push(regions[i].id);
|
||||||
}
|
}
|
||||||
data.source_regions = r.join();
|
data.source_regions = r.join();
|
||||||
|
|
||||||
if (scope.source && scope.source.value === 'ec2') {
|
if (sources_scope.source && sources_scope.source.value === 'ec2') {
|
||||||
// for ec2, validate variable data
|
// for ec2, validate variable data
|
||||||
data.source_vars = ToJSON(scope.envParseType, scope.source_vars, true);
|
data.source_vars = ToJSON(sources_scope.envParseType, sources_scope.source_vars, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parseError) {
|
if (!parseError) {
|
||||||
Rest.setUrl(scope.source_url);
|
Rest.setUrl(sources_scope.source_url);
|
||||||
Rest.put(data)
|
Rest.put(data)
|
||||||
.success(function () {
|
.success(function () {
|
||||||
scope.$emit('SaveComplete', false);
|
modal_scope.$emit('SaveComplete', false);
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
scope.$emit('SaveComplete', true);
|
modal_scope.$emit('SaveComplete', true);
|
||||||
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors(sources_scope, data, status, SourceForm, { hdr: 'Error!',
|
||||||
msg: 'Failed to update group inventory source. PUT status: ' + status });
|
msg: 'Failed to update group inventory source. PUT status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cancel
|
// Cancel
|
||||||
scope.cancelModal = function () {
|
modal_scope.cancelModal = function () {
|
||||||
try {
|
try {
|
||||||
$('#group-modal-dialog').dialog('close');
|
$('#group-modal-dialog').dialog('close');
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
if (scope.searchCleanup) {
|
if (modal_scope.searchCleanup) {
|
||||||
scope.searchCleanup();
|
modal_scope.searchCleanup();
|
||||||
}
|
}
|
||||||
WatchInventoryWindowResize();
|
WatchInventoryWindowResize();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
scope.saveGroup = function () {
|
modal_scope.saveGroup = function () {
|
||||||
Wait('start');
|
Wait('start');
|
||||||
var fld, data, json_data;
|
var fld, data, json_data;
|
||||||
|
|
||||||
json_data = ToJSON(scope.parseType, scope.variables);
|
json_data = ToJSON(properties_scope.parseType, properties_scope.variables);
|
||||||
|
|
||||||
data = {};
|
data = {};
|
||||||
for (fld in form.fields) {
|
for (fld in GroupForm.fields) {
|
||||||
data[fld] = scope[fld];
|
if (fld !== 'variables') {
|
||||||
|
data[fld] = properties_scope[fld];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.inventory = inventory_id;
|
data.inventory = inventory_id;
|
||||||
@@ -1008,52 +1170,51 @@ angular.module('GroupsHelper', ['RestServices', 'Utilities', 'ListGenerator', 'G
|
|||||||
Rest.setUrl(defaultUrl);
|
Rest.setUrl(defaultUrl);
|
||||||
Rest.put(data)
|
Rest.put(data)
|
||||||
.success(function () {
|
.success(function () {
|
||||||
if (scope.variables) {
|
if (properties_scope.variables) {
|
||||||
//update group variables
|
//update group variables
|
||||||
Rest.setUrl(scope.variable_url);
|
Rest.setUrl(properties_scope.variable_url);
|
||||||
Rest.put(json_data)
|
Rest.put(json_data)
|
||||||
.success(function () {
|
.success(function () {
|
||||||
scope.$emit('formSaveSuccess');
|
modal_scope.$emit('formSaveSuccess');
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
ProcessErrors(scope, data, status, form, { hdr: 'Error!',
|
ProcessErrors(modal_scope, data, status, null, { hdr: 'Error!',
|
||||||
msg: 'Failed to update group variables. PUT status: ' + status });
|
msg: 'Failed to update group variables. PUT status: ' + status });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
scope.$emit('formSaveSuccess');
|
modal_scope.$emit('formSaveSuccess');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
ProcessErrors(scope, data, status, form, {
|
ProcessErrors(properties_scope, data, status, GroupForm, { hdr: 'Error!',
|
||||||
hdr: 'Error!',
|
|
||||||
msg: 'Failed to update group: ' + group_id + '. PUT status: ' + status
|
msg: 'Failed to update group: ' + group_id + '. PUT status: ' + status
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start the update process
|
// Start the update process
|
||||||
scope.updateGroup = function () {
|
modal_scope.updateGroup = function () {
|
||||||
if (scope.source === "" || scope.source === null) {
|
if (sources_scope.source === "" || sources_scope.source === null) {
|
||||||
Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group, provide Source settings, ' +
|
Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group, provide Source settings, ' +
|
||||||
'and then run an update.', 'alert-info');
|
'and then run an update.', 'alert-info');
|
||||||
} else if (scope.status === 'updating') {
|
} else if (sources_scope.status === 'updating') {
|
||||||
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
|
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
|
||||||
scope.summary_fields.group.name + '</em>. Use the Refresh button to monitor the status.', 'alert-info');
|
sources_scope.summary_fields.group.name + '</em>. Use the Refresh button to monitor the status.', 'alert-info');
|
||||||
} else {
|
} else {
|
||||||
InventoryUpdate({
|
InventoryUpdate({
|
||||||
scope: scope,
|
scope: parent_scope,
|
||||||
group_id: group_id,
|
group_id: group_id,
|
||||||
url: scope.group_update_url,
|
url: properties_scope.group_update_url,
|
||||||
group_name: scope.name,
|
group_name: properties_scope.name,
|
||||||
group_source: scope.source.value
|
group_source: sources_scope.source.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Change the lookup and regions when the source changes
|
// Change the lookup and regions when the source changes
|
||||||
scope.sourceChange = function () {
|
sources_scope.sourceChange = function () {
|
||||||
SourceChange({ scope: scope, form: GroupForm });
|
SourceChange({ scope: sources_scope, form: SourceForm });
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ angular.module('SchedulesListDefinition', [])
|
|||||||
iterator: 'schedule',
|
iterator: 'schedule',
|
||||||
selectTitle: '',
|
selectTitle: '',
|
||||||
editTitle: 'Schedules',
|
editTitle: 'Schedules',
|
||||||
|
well: false,
|
||||||
index: true,
|
index: true,
|
||||||
hover: true,
|
hover: true,
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#scheduler-modal-dialog {
|
/*
|
||||||
|
#schedules-form -inventory group add/edit dialog
|
||||||
|
*/
|
||||||
|
|
||||||
|
#schedules-form {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 3px 3px 6px 0 #666;
|
||||||
|
padding: 8px 10px 15px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#scheduler-modal-dialog, #schedules-form {
|
||||||
display: none;
|
display: none;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -83,6 +94,13 @@
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-pull-up {
|
||||||
|
position: relative;
|
||||||
|
top: -15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.red-text {
|
.red-text {
|
||||||
color: #dd1b16;
|
color: #dd1b16;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,9 +130,11 @@ angular.module('AngularScheduler', ['underscore'])
|
|||||||
|
|
||||||
scope.startDateError = function(msg) {
|
scope.startDateError = function(msg) {
|
||||||
if (scope.scheduler_form) {
|
if (scope.scheduler_form) {
|
||||||
scope.scheduler_form_schedulerStartDt_error = msg;
|
if (scope.scheduler_form.schedulerStartDt) {
|
||||||
scope.scheduler_form.schedulerStartDt.$pristine = false;
|
scope.scheduler_form_schedulerStartDt_error = msg;
|
||||||
scope.scheduler_form.schedulerStartDt.$dirty = true;
|
scope.scheduler_form.schedulerStartDt.$pristine = false;
|
||||||
|
scope.scheduler_form.schedulerStartDt.$dirty = true;
|
||||||
|
}
|
||||||
$('#schedulerStartDt').removeClass('ng-pristine').removeClass('ng-valid').removeClass('ng-valid-custom-error')
|
$('#schedulerStartDt').removeClass('ng-pristine').removeClass('ng-valid').removeClass('ng-valid-custom-error')
|
||||||
.addClass('ng-dirty').addClass('ng-invalid').addClass('ng-invalid-custom-error');
|
.addClass('ng-dirty').addClass('ng-invalid').addClass('ng-invalid-custom-error');
|
||||||
}
|
}
|
||||||
@@ -141,8 +143,10 @@ angular.module('AngularScheduler', ['underscore'])
|
|||||||
scope.resetStartDate = function() {
|
scope.resetStartDate = function() {
|
||||||
if (scope.scheduler_form) {
|
if (scope.scheduler_form) {
|
||||||
scope.scheduler_form_schedulerStartDt_error = '';
|
scope.scheduler_form_schedulerStartDt_error = '';
|
||||||
scope.scheduler_form.schedulerStartDt.$setValidity('custom-error', true);
|
if (scope.scheduler_form.schedulerStartDt) {
|
||||||
scope.scheduler_form.schedulerStartDt.$setPristine();
|
scope.scheduler_form.schedulerStartDt.$setValidity('custom-error', true);
|
||||||
|
scope.scheduler_form.schedulerStartDt.$setPristine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -225,9 +229,11 @@ angular.module('AngularScheduler', ['underscore'])
|
|||||||
this.scope.scheduler_endDt_error = false;
|
this.scope.scheduler_endDt_error = false;
|
||||||
this.scope.resetStartDate();
|
this.scope.resetStartDate();
|
||||||
this.scope.scheduler_endDt_error = false;
|
this.scope.scheduler_endDt_error = false;
|
||||||
this.scope.scheduler_form.schedulerEndDt.$setValidity('custom-error', true);
|
if (this.scope.scheduler_form && this.scope.scheduler_form.schedulerEndDt) {
|
||||||
this.scope.scheduler_form.schedulerEndDt.$setPristine();
|
this.scope.scheduler_form.schedulerEndDt.$setValidity('custom-error', true);
|
||||||
this.scope.scheduler_form.$setPristine();
|
this.scope.scheduler_form.schedulerEndDt.$setPristine();
|
||||||
|
this.scope.scheduler_form.$setPristine();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check the input form for errors
|
// Check the input form for errors
|
||||||
@@ -333,7 +339,9 @@ angular.module('AngularScheduler', ['underscore'])
|
|||||||
// Clear the form, returning all elements to a default state
|
// Clear the form, returning all elements to a default state
|
||||||
this.clear = function() {
|
this.clear = function() {
|
||||||
this.clearErrors();
|
this.clearErrors();
|
||||||
this.scope.scheduler_form.schedulerName.$setPristine();
|
if (this.scope.scheduler_form && this.scope.scheduler_form.schedulerName) {
|
||||||
|
this.scope.scheduler_form.schedulerName.$setPristine();
|
||||||
|
}
|
||||||
this.scope.setDefaults();
|
this.scope.setDefaults();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,27 @@
|
|||||||
<div id="groups-container" class="col-lg-6"></div>
|
<div id="groups-container" class="col-lg-6"></div>
|
||||||
<div id="hosts-container" class="col-lg-6"></div>
|
<div id="hosts-container" class="col-lg-6"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="inventory-modal-container"></div>
|
<div id="inventory-modal-container"></div>
|
||||||
|
|
||||||
|
<div id="group-modal-dialog" style="display: none;">
|
||||||
|
<ul id="group_tabs" class="nav nav-tabs">
|
||||||
|
<li class="active"><a id="properties_link" ng-click="toggleTab($event, 'properties_link', 'group_tabs')"
|
||||||
|
href="#properties-tab" data-toggle="tab">Properties</a></li>
|
||||||
|
<li><a id="source_link" ng-click="toggleTab($event, 'source_link', 'group_tabs')"
|
||||||
|
href="#sources-tab" data-toggle="tab">Source</a></li>
|
||||||
|
<li><a id="schedules_link" ng-click="toggleTab($event, 'schedules_link', 'group_tabs')"
|
||||||
|
href="#schedules-tab" data-toggle="tab">Schedule</a></li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane active" id="properties-tab"></div>
|
||||||
|
<div class="tab-pane" id="sources-tab"></div>
|
||||||
|
<div class="tab-pane" id="schedules-tab">
|
||||||
|
<div id="schedules-list"></div>
|
||||||
|
<div id="schedules-form"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
43
awx/ui/static/sample/data/schedules/inventory/data.json
Normal file
43
awx/ui/static/sample/data/schedules/inventory/data.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"count": 3,
|
||||||
|
"next": null,
|
||||||
|
"previous": null,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"job_template": null,
|
||||||
|
"inventory_source": 8,
|
||||||
|
"project": null,
|
||||||
|
"job_class": "inventory:sync",
|
||||||
|
"job_type": "inventory_sync",
|
||||||
|
"name": "Hourly",
|
||||||
|
"dtstart": "2014-03-10T17:00:00.000Z" ,
|
||||||
|
"dtend": null,
|
||||||
|
"rrule": "FREQ=HOURLY;DTSTART=20140310T170000Z;INTERVAL=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"job_template": null,
|
||||||
|
"inventory_source": 8,
|
||||||
|
"project": null,
|
||||||
|
"job_class": "inventory:sync",
|
||||||
|
"job_type": "inventory_sync",
|
||||||
|
"name": "Weekly",
|
||||||
|
"dtstart": "2014-03-17T13:00:00.000Z",
|
||||||
|
"dtend": null,
|
||||||
|
"rrule": "FREQ=WEEKLY;DTSTART=20140317T130000Z;INTERVAL=1;COUNT=10;BYDAY=MO"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"job_template": null,
|
||||||
|
"inventory_source": 8,
|
||||||
|
"project": null,
|
||||||
|
"job_class": "inventory:sync",
|
||||||
|
"job_type": "inventory_sync",
|
||||||
|
"name": "Monthly",
|
||||||
|
"dtstart": "2014-04-06T01:00:00.000Z",
|
||||||
|
"dtend": "2020-03-01T01:00:00.000Z",
|
||||||
|
"rrule": "FREQ=MONTHLY;DTSTART=20140406T010000Z;INTERVAL=1;UNTIL=20200301T010000Z;BYMONTHDAY=1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -96,6 +96,7 @@
|
|||||||
<script src="{{ STATIC_URL }}js/forms/ActivityDetail.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/ActivityDetail.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/JobSummary.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/JobSummary.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/LicenseForm.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/LicenseForm.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/forms/Source.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Organizations.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Organizations.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Admins.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Admins.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user