1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 15:21:13 +03:00

Fixed jt admin edit bug

Signed-off-by: mabashian <mabashia@redhat.com>
This commit is contained in:
mabashian 2017-09-13 11:38:56 -04:00
parent 7e754e20ae
commit 28fa5077d5
No known key found for this signature in database
GPG Key ID: 436B8D5EDC704CE3
10 changed files with 314 additions and 252 deletions

View File

@ -37,6 +37,8 @@
$scope.mode = "add";
$scope.parseType = 'yaml';
$scope.credentialNotPresent = false;
$scope.canChangeProject = true;
$scope.canChangeInventory = true;
md5Setup({
scope: $scope,

View File

@ -18,13 +18,15 @@ export default
'Empty', 'Prompt', 'ToJSON', 'GetChoices', 'CallbackHelpInit',
'InitiatePlaybookRun' , 'initSurvey', '$state', 'CreateSelect2',
'ToggleNotification','$q', 'InstanceGroupsService', 'InstanceGroupsData', 'MultiCredentialService', 'availableLabels',
'canChangeProject', 'canChangeInventory', 'jobTemplateData', 'ParseVariableString',
function(
$filter, $scope, $rootScope,
$location, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
ProcessErrors, GetBasePath, md5Setup,
ParseTypeChange, Wait, selectedLabels, i18n,
Empty, Prompt, ToJSON, GetChoices, CallbackHelpInit, InitiatePlaybookRun, SurveyControllerInit, $state,
CreateSelect2, ToggleNotification, $q, InstanceGroupsService, InstanceGroupsData, MultiCredentialService, availableLabels
CreateSelect2, ToggleNotification, $q, InstanceGroupsService, InstanceGroupsData, MultiCredentialService, availableLabels,
canChangeProject, canChangeInventory, jobTemplateData, ParseVariableString
) {
$scope.$watch('job_template_obj.summary_fields.user_capabilities.edit', function(val) {
@ -47,6 +49,7 @@ export default
function init() {
CallbackHelpInit({ scope: $scope });
$scope.playbook_options = null;
$scope.playbook = null;
$scope.mode = 'edit';
@ -57,6 +60,8 @@ export default
$scope.surveyTooltip = i18n._('Surveys allow users to be prompted at job launch with a series of questions related to the job. This allows for variables to be defined that affect the playbook run at time of launch.');
$scope.job_tag_options = [];
$scope.skip_tag_options = [];
$scope.canChangeProject = canChangeProject;
$scope.canChangeInventory = canChangeInventory;
SurveyControllerInit({
scope: $scope,
@ -253,7 +258,194 @@ export default
$scope.rmoveLoadJobs();
}
$scope.removeLoadJobs = $scope.$on('LoadJobs', function() {
$scope.fillJobTemplate();
$scope.job_template_obj = jobTemplateData;
$scope.name = jobTemplateData.name;
var fld, i;
for (fld in form.fields) {
if (fld !== 'variables' && fld !== 'survey' && fld !== 'forks' && jobTemplateData[fld] !== null && jobTemplateData[fld] !== undefined) {
if (form.fields[fld].type === 'select') {
if ($scope[fld + '_options'] && $scope[fld + '_options'].length > 0) {
for (i = 0; i < $scope[fld + '_options'].length; i++) {
if (jobTemplateData[fld] === $scope[fld + '_options'][i].value) {
$scope[fld] = $scope[fld + '_options'][i];
}
}
} else {
$scope[fld] = jobTemplateData[fld];
}
} else {
$scope[fld] = jobTemplateData[fld];
if(!Empty(jobTemplateData.summary_fields.survey)) {
$scope.survey_exists = true;
}
}
master[fld] = $scope[fld];
}
if (fld === 'forks') {
if (jobTemplateData[fld] !== 0) {
$scope[fld] = jobTemplateData[fld];
master[fld] = $scope[fld];
}
}
if (fld === 'variables') {
// Parse extra_vars, converting to YAML.
$scope.variables = ParseVariableString(jobTemplateData.extra_vars);
master.variables = $scope.variables;
}
if (form.fields[fld].type === 'lookup' && jobTemplateData.summary_fields[form.fields[fld].sourceModel]) {
$scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
jobTemplateData.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
$scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
}
if (form.fields[fld].type === 'checkbox_group') {
for(var j=0; j<form.fields[fld].fields.length; j++) {
$scope[form.fields[fld].fields[j].name] = jobTemplateData[form.fields[fld].fields[j].name];
}
}
}
Wait('stop');
$scope.url = jobTemplateData.url;
$scope.survey_enabled = jobTemplateData.survey_enabled;
$scope.ask_variables_on_launch = (jobTemplateData.ask_variables_on_launch) ? true : false;
master.ask_variables_on_launch = $scope.ask_variables_on_launch;
$scope.ask_verbosity_on_launch = (jobTemplateData.ask_verbosity_on_launch) ? true : false;
master.ask_verbosity_on_launch = $scope.ask_verbosity_on_launch;
$scope.ask_limit_on_launch = (jobTemplateData.ask_limit_on_launch) ? true : false;
master.ask_limit_on_launch = $scope.ask_limit_on_launch;
$scope.ask_tags_on_launch = (jobTemplateData.ask_tags_on_launch) ? true : false;
master.ask_tags_on_launch = $scope.ask_tags_on_launch;
$scope.ask_skip_tags_on_launch = (jobTemplateData.ask_skip_tags_on_launch) ? true : false;
master.ask_skip_tags_on_launch = $scope.ask_skip_tags_on_launch;
$scope.ask_diff_mode_on_launch = (jobTemplateData.ask_diff_mode_on_launch) ? true : false;
master.ask_diff_mode_on_launch = $scope.ask_diff_mode_on_launch;
$scope.job_tag_options = (jobTemplateData.job_tags) ? jobTemplateData.job_tags.split(',')
.map((i) => ({name: i, label: i, value: i})) : [];
$scope.job_tags = $scope.job_tag_options;
master.job_tags = $scope.job_tags;
$scope.skip_tag_options = (jobTemplateData.skip_tags) ? jobTemplateData.skip_tags.split(',')
.map((i) => ({name: i, label: i, value: i})) : [];
$scope.skip_tags = $scope.skip_tag_options;
master.skip_tags = $scope.skip_tags;
$scope.ask_job_type_on_launch = (jobTemplateData.ask_job_type_on_launch) ? true : false;
master.ask_job_type_on_launch = $scope.ask_job_type_on_launch;
$scope.ask_inventory_on_launch = (jobTemplateData.ask_inventory_on_launch) ? true : false;
master.ask_inventory_on_launch = $scope.ask_inventory_on_launch;
$scope.ask_credential_on_launch = (jobTemplateData.ask_credential_on_launch) ? true : false;
master.ask_credential_on_launch = $scope.ask_credential_on_launch;
if (jobTemplateData.host_config_key) {
$scope.example_config_key = jobTemplateData.host_config_key;
}
$scope.example_template_id = id;
$scope.setCallbackHelp();
$scope.callback_url = $scope.callback_server_path + ((jobTemplateData.related.callback) ? jobTemplateData.related.callback :
GetBasePath('job_templates') + id + '/callback/');
master.callback_url = $scope.callback_url;
$scope.can_edit = jobTemplateData.summary_fields.user_capabilities.edit;
if($scope.job_template_obj.summary_fields.user_capabilities.edit) {
MultiCredentialService.loadCredentials(jobTemplateData)
.then(([selectedCredentials, credTypes, credTypeOptions,
credTags]) => {
$scope.selectedCredentials = selectedCredentials;
$scope.credential_types = credTypes;
$scope.credentialTypeOptions = credTypeOptions;
$scope.credentialsToPost = credTags;
$scope.$emit('jobTemplateLoaded', master);
});
}
else {
if (jobTemplateData.summary_fields.credential) {
$scope.selectedCredentials.machine = jobTemplateData.summary_fields.credential;
}
if (jobTemplateData.summary_fields.vault_credential) {
$scope.selectedCredentials.vault = jobTemplateData.summary_fields.vault_credential;
}
// Extra credentials are not included in summary_fields so we have to go
// out and get them ourselves.
let defers = [],
typesArray = [],
credTypeOptions;
Rest.setUrl(jobTemplateData.related.extra_credentials);
defers.push(Rest.get()
.then((data) => {
$scope.selectedCredentials.extra = data.data.results;
})
.catch(({data, status}) => {
ProcessErrors(null, data, status, null,
{
hdr: 'Error!',
msg: 'Failed to get extra credentials. ' +
'Get returned status: ' +
status
});
}));
defers.push(MultiCredentialService.getCredentialTypes()
.then(({credential_types, credentialTypeOptions}) => {
typesArray = Object.keys(credential_types).map(key => credential_types[key]);
credTypeOptions = credentialTypeOptions;
})
);
return $q.all(defers).then(() => {
let machineAndVaultCreds = [],
extraCreds = [];
if($scope.selectedCredentials.machine) {
machineAndVaultCreds.push($scope.selectedCredentials.machine);
}
if($scope.selectedCredentials.vault) {
machineAndVaultCreds.push($scope.selectedCredentials.vault);
}
machineAndVaultCreds.map(cred => ({
name: cred.name,
id: cred.id,
postType: cred.postType,
kind: typesArray
.filter(type => {
return cred.kind === type.kind || parseInt(cred.credential_type) === type.value;
})[0].name + ":"
}));
extraCreds = extraCreds.concat($scope.selectedCredentials.extra).map(cred => ({
name: cred.name,
id: cred.id,
postType: cred.postType,
kind: credTypeOptions
.filter(type => {
return parseInt(cred.credential_type) === type.value;
})[0].name + ":"
}));
$scope.credentialsToPost = machineAndVaultCreds.concat(extraCreds);
$scope.$emit('jobTemplateLoaded', master);
});
}
});
if ($scope.removeChoicesReady) {

View File

@ -2,14 +2,7 @@ export default
function CallbackHelpInit($q, $location, GetBasePath, Rest, JobTemplateForm, GenerateForm, $stateParams, ProcessErrors,
ParseVariableString, Empty, Wait, MultiCredentialService, $rootScope) {
return function(params) {
var scope = params.scope,
defaultUrl = GetBasePath('job_templates'),
// generator = GenerateForm,
form = JobTemplateForm(),
// loadingFinishedCount = 0,
// base = $location.path().replace(/^\//, '').split('/')[0],
master = {},
id = $stateParams.job_template_id;
var scope = params.scope;
// checkSCMStatus, getPlaybooks, callback,
// choicesCount = 0;
@ -44,211 +37,6 @@ export default
scope.example_config_key = '5a8ec154832b780b9bdef1061764ae5a';
scope.example_template_id = 'N';
scope.setCallbackHelp();
// this fills the job template form both on copy of the job template
// and on edit
scope.fillJobTemplate = function(){
// id = id || $rootScope.copy.id;
// Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl + id);
Rest.get()
.success(function (data) {
scope.job_template_obj = data;
scope.name = data.name;
var fld, i;
for (fld in form.fields) {
if (fld !== 'variables' && fld !== 'survey' && fld !== 'forks' && data[fld] !== null && data[fld] !== undefined) {
if (form.fields[fld].type === 'select') {
if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) {
for (i = 0; i < scope[fld + '_options'].length; i++) {
if (data[fld] === scope[fld + '_options'][i].value) {
scope[fld] = scope[fld + '_options'][i];
}
}
} else {
scope[fld] = data[fld];
}
} else {
scope[fld] = data[fld];
if(!Empty(data.summary_fields.survey)) {
scope.survey_exists = true;
}
}
master[fld] = scope[fld];
}
if (fld === 'forks') {
if (data[fld] !== 0) {
scope[fld] = data[fld];
master[fld] = scope[fld];
}
}
if (fld === 'variables') {
// Parse extra_vars, converting to YAML.
scope.variables = ParseVariableString(data.extra_vars);
master.variables = scope.variables;
}
if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
scope[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] =
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
}
if (form.fields[fld].type === 'checkbox_group') {
for(var j=0; j<form.fields[fld].fields.length; j++) {
scope[form.fields[fld].fields[j].name] = data[form.fields[fld].fields[j].name];
}
}
}
Wait('stop');
scope.url = data.url;
scope.survey_enabled = data.survey_enabled;
scope.ask_variables_on_launch = (data.ask_variables_on_launch) ? true : false;
master.ask_variables_on_launch = scope.ask_variables_on_launch;
scope.ask_verbosity_on_launch = (data.ask_verbosity_on_launch) ? true : false;
master.ask_verbosity_on_launch = scope.ask_verbosity_on_launch;
scope.ask_limit_on_launch = (data.ask_limit_on_launch) ? true : false;
master.ask_limit_on_launch = scope.ask_limit_on_launch;
scope.ask_tags_on_launch = (data.ask_tags_on_launch) ? true : false;
master.ask_tags_on_launch = scope.ask_tags_on_launch;
scope.ask_skip_tags_on_launch = (data.ask_skip_tags_on_launch) ? true : false;
master.ask_skip_tags_on_launch = scope.ask_skip_tags_on_launch;
scope.ask_diff_mode_on_launch = (data.ask_diff_mode_on_launch) ? true : false;
master.ask_diff_mode_on_launch = scope.ask_diff_mode_on_launch;
scope.job_tag_options = (data.job_tags) ? data.job_tags.split(',')
.map((i) => ({name: i, label: i, value: i})) : [];
scope.job_tags = scope.job_tag_options;
master.job_tags = scope.job_tags;
scope.skip_tag_options = (data.skip_tags) ? data.skip_tags.split(',')
.map((i) => ({name: i, label: i, value: i})) : [];
scope.skip_tags = scope.skip_tag_options;
master.skip_tags = scope.skip_tags;
scope.ask_job_type_on_launch = (data.ask_job_type_on_launch) ? true : false;
master.ask_job_type_on_launch = scope.ask_job_type_on_launch;
scope.ask_inventory_on_launch = (data.ask_inventory_on_launch) ? true : false;
master.ask_inventory_on_launch = scope.ask_inventory_on_launch;
scope.ask_credential_on_launch = (data.ask_credential_on_launch) ? true : false;
master.ask_credential_on_launch = scope.ask_credential_on_launch;
if (data.host_config_key) {
scope.example_config_key = data.host_config_key;
}
scope.example_template_id = id;
scope.setCallbackHelp();
scope.callback_url = scope.callback_server_path + ((data.related.callback) ? data.related.callback :
GetBasePath('job_templates') + id + '/callback/');
master.callback_url = scope.callback_url;
scope.can_edit = data.summary_fields.user_capabilities.edit;
if(scope.job_template_obj.summary_fields.user_capabilities.edit) {
MultiCredentialService.loadCredentials(data)
.then(([selectedCredentials, credTypes, credTypeOptions,
credTags]) => {
scope.selectedCredentials = selectedCredentials;
scope.credential_types = credTypes;
scope.credentialTypeOptions = credTypeOptions;
scope.credentialsToPost = credTags;
scope.$emit('jobTemplateLoaded', master);
});
}
else {
if (data.summary_fields.credential) {
scope.selectedCredentials.machine = data.summary_fields.credential;
}
if (data.summary_fields.vault_credential) {
scope.selectedCredentials.vault = data.summary_fields.vault_credential;
}
// Extra credentials are not included in summary_fields so we have to go
// out and get them ourselves.
let defers = [],
typesArray = [],
credTypeOptions;
Rest.setUrl(data.related.extra_credentials);
defers.push(Rest.get()
.then((data) => {
scope.selectedCredentials.extra = data.data.results;
})
.catch(({data, status}) => {
ProcessErrors(null, data, status, null,
{
hdr: 'Error!',
msg: 'Failed to get extra credentials. ' +
'Get returned status: ' +
status
});
}));
defers.push(MultiCredentialService.getCredentialTypes()
.then(({credential_types, credentialTypeOptions}) => {
typesArray = Object.keys(credential_types).map(key => credential_types[key]);
credTypeOptions = credentialTypeOptions;
})
);
return $q.all(defers).then(() => {
let machineAndVaultCreds = [],
extraCreds = [];
if(scope.selectedCredentials.machine) {
machineAndVaultCreds.push(scope.selectedCredentials.machine);
}
if(scope.selectedCredentials.vault) {
machineAndVaultCreds.push(scope.selectedCredentials.vault);
}
machineAndVaultCreds.map(cred => ({
name: cred.name,
id: cred.id,
postType: cred.postType,
kind: typesArray
.filter(type => {
return cred.kind === type.kind || parseInt(cred.credential_type) === type.value;
})[0].name + ":"
}));
extraCreds = extraCreds.concat(scope.selectedCredentials.extra).map(cred => ({
name: cred.name,
id: cred.id,
postType: cred.postType,
kind: credTypeOptions
.filter(type => {
return parseInt(cred.credential_type) === type.value;
})[0].name + ":"
}));
scope.credentialsToPost = machineAndVaultCreds.concat(extraCreds);
scope.$emit('jobTemplateLoaded', master);
});
}
})
.error(function (data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to retrieve job template: ' + $stateParams.id + '. GET status: ' + status
});
});
};
};
}

View File

@ -85,7 +85,7 @@ function(NotificationsList, CompletedJobsList, i18n) {
ngChange: 'job_template_form.inventory_name.$validate()',
text: i18n._('Prompt on launch')
},
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate) || !canChangeInventory'
},
project: {
label: i18n._('Project'),
@ -100,13 +100,14 @@ function(NotificationsList, CompletedJobsList, i18n) {
dataTitle: i18n._('Project'),
dataPlacement: 'right',
dataContainer: "body",
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate)'
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate) || !canChangeProject',
awLookupWhen: 'canChangeProject'
},
playbook: {
label: i18n._('Playbook'),
type:'select',
ngOptions: 'book for book in playbook_options track by book',
ngDisabled: "!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate) || disablePlaybookBecausePermissionDenied",
ngDisabled: "!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate) || !canChangeProject",
id: 'playbook-select',
required: true,
column: 1,

View File

@ -14,7 +14,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
.then(kinds => {
scope.credentialKinds = kinds;
scope.credentialKind = "" + kinds.Machine;
scope.credentialKind = scope.selectedCredentials.machine && scope.selectedCredentials.machine.readOnly ? (scope.selectedCredentials.vault && scope.selectedCredentials.vault.readOnly ? "" + kinds.Network : "" + kinds.Vault) : "" + kinds.Machine;
scope.showModal = function() {
$('#multi-credential-modal').modal('show');
@ -50,6 +50,22 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
.then(({credential_types, credentialTypeOptions}) => {
scope.credential_types = credential_types;
scope.credentialTypeOptions = credentialTypeOptions;
scope.allCredentialTypeOptions = _.cloneDeep(credentialTypeOptions);
// We want to hide machine and vault dropdown options if a credential
// has already been selected for those types and the user interacting
// with the form doesn't have the ability to change them
for(let i=scope.credentialTypeOptions.length - 1; i >=0; i--) {
if((scope.selectedCredentials.machine &&
scope.selectedCredentials.machine.credential_type_id === scope.credentialTypeOptions[i].value &&
scope.selectedCredentials.machine.readOnly) ||
(scope.selectedCredentials.vault &&
scope.selectedCredentials.vault.credential_type_id === scope.credentialTypeOptions[i].value &&
scope.selectedCredentials.vault.readOnly)) {
scope.credentialTypeOptions.splice(i, 1);
}
}
scope.$emit('multiCredentialModalLinked');
});
});
@ -70,7 +86,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
$scope.credTags = MultiCredentialService
.updateCredentialTags($scope.selectedCredentials,
$scope.credentialTypeOptions);
$scope.allCredentialTypeOptions);
};
let updateMachineCredentialList = function() {
@ -85,7 +101,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
$scope.credTags = MultiCredentialService
.updateCredentialTags($scope.selectedCredentials,
$scope.credentialTypeOptions);
$scope.allCredentialTypeOptions);
};
let updateVaultCredentialList = function() {
@ -100,7 +116,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
$scope.credTags = MultiCredentialService
.updateCredentialTags($scope.selectedCredentials,
$scope.credentialTypeOptions);
$scope.allCredentialTypeOptions);
};
let uncheckAllCredentials = function() {
@ -110,7 +126,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile'
$scope.credTags = MultiCredentialService
.updateCredentialTags($scope.selectedCredentials,
$scope.credentialTypeOptions);
$scope.allCredentialTypeOptions);
};
let init = function() {

View File

@ -27,13 +27,13 @@
class="MultiCredential-tagContainer ng-scope"
ng-repeat="tag in credTags track by $index">
<div class="MultiCredential-deleteContainer"
ng-click="removeCredential(tag.id)">
ng-click="removeCredential(tag.id)"
ng-if="!tag.readOnly">
<i class="fa fa-times
MultiCredential-tagDelete">
</i>
</div>
<div class="MultiCredential-tag
MultiCredential-tag--deletable">
<div class="MultiCredential-tag" ng-class="tag.readOnly ? 'MultiCredential-tag--disabled' : 'MultiCredential-tag--deletable'">
<span
class="MultiCredential-name--label
ng-binding">

View File

@ -51,6 +51,10 @@
padding-left: 15px;
}
.MultiCredential-tag--disabled {
background-color: @default-icon;
}
.MultiCredential-tag--deletable {
margin-right: 0px;
border-top-left-radius: 0px;

View File

@ -23,12 +23,12 @@
ng-repeat="tag in credentialsToPost track by $index">
<div class="MultiCredential-deleteContainer"
ng-click="removeCredential(tag.id)"
ng-hide="fieldIsDisabled">
ng-hide="fieldIsDisabled || tag.readOnly">
<i class="fa fa-times MultiCredential-tagDelete">
</i>
</div>
<div class="MultiCredential-tag"
ng-class="{'MultiCredential-tag--deletable': !fieldIsDisabled}">
ng-class="{'MultiCredential-tag--deletable': !fieldIsDisabled && !tag.readOnly, 'MultiCredential-tag--disabled': tag.readOnly}">
<span class="MultiCredential-name--label
ng-binding">
{{ tag.kind }}

View File

@ -138,6 +138,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
name: cred.name,
id: cred.id,
postType: cred.postType,
readOnly: cred.readOnly,
kind: typeOpts
.filter(type => {
return parseInt(cred.credential_type) === type.value;
@ -190,6 +191,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
/* User doesn't have read access to the machine credential, so use summary_fields */
selectedCredentials.machine = job_template_obj.summary_fields.credential;
selectedCredentials.machine.credential_type = job_template_obj.summary_fields.credential.credential_type_id;
selectedCredentials.machine.readOnly = true;
} else {
ProcessErrors(
null, data, status, null,
@ -214,6 +216,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
/* User doesn't have read access to the vault credential, so use summary_fields */
selectedCredentials.vault = job_template_obj.summary_fields.vault_credential;
selectedCredentials.vault.credential_type = job_template_obj.summary_fields.vault_credential.credential_type_id;
selectedCredentials.vault.readOnly = true;
} else {
ProcessErrors(
null, data, status, null,
@ -240,6 +243,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro
selectedCredentials.extra = job_template_obj.summary_fields.extra_credentials;
_.map(selectedCredentials.extra, (cred) => {
cred.credential_type = cred.credential_type_id;
cred.readOnly = true;
return cred;
});
} else {

View File

@ -137,6 +137,61 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplates.
},
resolve: {
edit: {
jobTemplateData: ['$stateParams', 'TemplatesService', 'ProcessErrors',
function($stateParams, TemplatesService, ProcessErrors) {
return TemplatesService.getJobTemplate($stateParams.job_template_id)
.then(function(res) {
return res.data;
}).catch(function(response){
ProcessErrors(null, response.data, response.status, null, {
hdr: 'Error!',
msg: 'Failed to get job template. GET returned status: ' +
response.status
});
});
}],
canChangeProject: ['Rest', 'ProcessErrors', 'jobTemplateData',
function(Rest, ProcessErrors, jobTemplateData) {
Rest.setUrl(jobTemplateData.related.project);
return Rest.get()
.then(() => {
return true;
})
.catch(({data, status}) => {
if (status === 403) {
/* User doesn't have read access to the project, no problem. */
} else {
ProcessErrors(null, data, status, null, {
hdr: 'Error!',
msg: 'Failed to get project. GET returned ' +
'status: ' + status
});
}
return false;
});
}],
canChangeInventory: ['Rest', 'ProcessErrors', 'jobTemplateData',
function(Rest, ProcessErrors, jobTemplateData) {
Rest.setUrl(jobTemplateData.related.inventory);
return Rest.get()
.then(() => {
return true;
})
.catch(({data, status}) => {
if (status === 403) {
/* User doesn't have read access to the project, no problem. */
} else {
ProcessErrors(null, data, status, null, {
hdr: 'Error!',
msg: 'Failed to get project. GET returned ' +
'status: ' + status
});
}
return false;
});
}],
InstanceGroupsData: ['$stateParams', 'Rest', 'GetBasePath', 'ProcessErrors',
function($stateParams, Rest, GetBasePath, ProcessErrors){
let path = `${GetBasePath('job_templates')}${$stateParams.job_template_id}/instance_groups/`;