mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 08:21:15 +03:00
Merge pull request #4178 from mabashian/3583-copy-workflow
Implemented WFJT copy and moved JT copy away from a viewless route
This commit is contained in:
commit
3d56c2b50f
@ -27,21 +27,21 @@ export default
|
||||
first_name: {
|
||||
label: i18n._('First Name'),
|
||||
type: 'text',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||
required: true,
|
||||
capitalize: true
|
||||
},
|
||||
last_name: {
|
||||
label: i18n._('Last Name'),
|
||||
type: 'text',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||
required: true,
|
||||
capitalize: true
|
||||
},
|
||||
email: {
|
||||
label: i18n._('Email'),
|
||||
type: 'email',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||
required: true,
|
||||
autocomplete: false
|
||||
},
|
||||
@ -53,7 +53,7 @@ export default
|
||||
init: true
|
||||
},
|
||||
autocomplete: false,
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: i18n._('Organization'),
|
||||
@ -64,7 +64,7 @@ export default
|
||||
sourceField: 'name',
|
||||
required: true,
|
||||
excludeMode: 'edit',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
password: {
|
||||
label: i18n._('Password'),
|
||||
@ -76,7 +76,7 @@ export default
|
||||
ngChange: "clearPWConfirm('password_confirm')",
|
||||
autocomplete: false,
|
||||
chkPass: true,
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
password_confirm: {
|
||||
label: i18n._('Confirm Password'),
|
||||
@ -88,7 +88,7 @@ export default
|
||||
awPassMatch: true,
|
||||
associated: 'password',
|
||||
autocomplete: false,
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
user_type: {
|
||||
label: i18n._('User Type'),
|
||||
@ -97,23 +97,23 @@ export default
|
||||
disableChooseOption: true,
|
||||
ngModel: 'user_type',
|
||||
ngShow: 'current_user["is_superuser"]',
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
},
|
||||
|
||||
buttons: {
|
||||
cancel: {
|
||||
ngClick: 'formCancel()',
|
||||
ngShow: '(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngShow: '(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
close: {
|
||||
ngClick: 'formCancel()',
|
||||
ngShow: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngShow: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
save: {
|
||||
ngClick: 'formSave()',
|
||||
ngDisabled: true,
|
||||
ngShow: '(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
||||
ngShow: '(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -98,7 +98,7 @@ export default
|
||||
},
|
||||
copy: {
|
||||
label: i18n._('Copy'),
|
||||
'ui-sref': 'templates.copy({id: template.id})',
|
||||
ngClick: 'copyTemplate(template)',
|
||||
"class": 'btn-danger btn-xs',
|
||||
awToolTip: i18n._('Copy template'),
|
||||
dataPlacement: 'top',
|
||||
|
@ -99,6 +99,21 @@
|
||||
color: @btn-txt-sel;
|
||||
}
|
||||
|
||||
.Modal-primaryButton {
|
||||
background-color: @default-link;
|
||||
color: @default-bg;
|
||||
text-transform: uppercase;
|
||||
border-radius: 5px;
|
||||
transition: background-color 0.2s;
|
||||
padding-left:15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.Modal-primaryButton:hover {
|
||||
background-color: @default-link-hov;
|
||||
color: @default-bg;
|
||||
}
|
||||
|
||||
.Modal-errorButton:focus {
|
||||
color: @btn-txt-sel;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ angular.module('PromptDialog', ['Utilities', 'sanitizeFilter'])
|
||||
|
||||
cls = (params['class'] === null || params['class'] === undefined) ? 'Modal-errorButton' : params['class'];
|
||||
|
||||
$('#prompt_action_btn').removeClass(cls).addClass(cls);
|
||||
$('#prompt_action_btn').removeClass('Modal-errorButton Modal-primaryButton').addClass(cls);
|
||||
|
||||
// bootstrap modal's have an open defect with disallowing tab index's of the background of the modal
|
||||
// This will keep the tab indexing on the modal's focus. This is to fix an issue with tabbing working when
|
||||
|
@ -39,7 +39,7 @@
|
||||
return Rest.post(data.results[0])
|
||||
.success(function(job_template_res){
|
||||
// also copy any associated survey_spec
|
||||
if (data.results[0].related.survey_spec){
|
||||
if (data.results[0].summary_fields.survey){
|
||||
return self.copySurvey(data.results[0], job_template_res).success( () => job_template_res);
|
||||
}
|
||||
else{
|
||||
@ -54,6 +54,22 @@
|
||||
buildName: function(name){
|
||||
var result = name.split('@')[0];
|
||||
return result;
|
||||
},
|
||||
getWorkflowCopy: function(id) {
|
||||
let url = GetBasePath('workflow_job_templates');
|
||||
|
||||
url = url + id + '/copy';
|
||||
|
||||
Rest.setUrl(url);
|
||||
return Rest.get();
|
||||
},
|
||||
copyWorkflow: function(id) {
|
||||
let url = GetBasePath('workflow_job_templates');
|
||||
|
||||
url = url + id + '/copy';
|
||||
|
||||
Rest.setUrl(url);
|
||||
return Rest.post();
|
||||
}
|
||||
};
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
[ 'Wait', '$state', '$scope', 'jobTemplateCopyService',
|
||||
'ProcessErrors', '$rootScope',
|
||||
function(Wait, $state, $scope, jobTemplateCopyService,
|
||||
ProcessErrors, $rootScope){
|
||||
// GETs the job_template to copy
|
||||
// POSTs a new job_template
|
||||
// routes to JobTemplates.edit when finished
|
||||
var init = function(){
|
||||
Wait('start');
|
||||
jobTemplateCopyService.get($state.params.id)
|
||||
.success(function(res){
|
||||
jobTemplateCopyService.set(res)
|
||||
.success(function(res){
|
||||
Wait('stop');
|
||||
if(res.type && res.type === 'job_template') {
|
||||
$state.go('templates.editJobTemplate', {id: res.id}, {reload: true});
|
||||
}
|
||||
// Workflow edit to be implemented post 3.1 but we'll need to handle the
|
||||
// state transition for that here
|
||||
});
|
||||
})
|
||||
.error(function(res, status){
|
||||
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
|
||||
msg: 'Call failed. Return status: '+ status});
|
||||
});
|
||||
};
|
||||
init();
|
||||
}
|
||||
];
|
@ -1,12 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
|
||||
export default {
|
||||
name: 'templates.copy',
|
||||
route: '/:id/copy',
|
||||
controller: 'jobTemplateCopyController'
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import controller from './job-templates-copy.controller';
|
||||
import route from './job-templates-copy.route';
|
||||
import service from './job-templates-copy.service';
|
||||
|
||||
export default
|
||||
angular.module('templates.copy', [])
|
||||
.service('jobTemplateCopyService', service)
|
||||
.controller('jobTemplateCopyController', controller)
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
$stateExtender.addState(route);
|
||||
}]);
|
@ -7,12 +7,12 @@
|
||||
export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Alert',
|
||||
'TemplateList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
|
||||
'InitiatePlaybookRun', 'Wait', '$state', '$filter', 'Dataset', 'rbacUiControlService', 'TemplatesService',
|
||||
'QuerySet', 'GetChoices',
|
||||
'QuerySet', 'GetChoices', 'TemplateCopyService',
|
||||
function(
|
||||
$scope, $rootScope, $location, $stateParams, Rest, Alert,
|
||||
TemplateList, Prompt, ClearScope, ProcessErrors, GetBasePath,
|
||||
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, TemplatesService,
|
||||
qs, GetChoices
|
||||
qs, GetChoices, TemplateCopyService
|
||||
) {
|
||||
ClearScope();
|
||||
|
||||
@ -192,5 +192,101 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Al
|
||||
Alert('Error: Unable to schedule job', 'Template parameter is missing');
|
||||
}
|
||||
};
|
||||
|
||||
$scope.copyTemplate = function(template) {
|
||||
if(template) {
|
||||
if(template.type && template.type === 'job_template') {
|
||||
Wait('start');
|
||||
TemplateCopyService.get(template.id)
|
||||
.success(function(res){
|
||||
TemplateCopyService.set(res)
|
||||
.success(function(res){
|
||||
Wait('stop');
|
||||
if(res.type && res.type === 'job_template') {
|
||||
$state.go('templates.editJobTemplate', {job_template_id: res.id}, {reload: true});
|
||||
}
|
||||
});
|
||||
})
|
||||
.error(function(res, status){
|
||||
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
|
||||
msg: 'Call failed. Return status: '+ status});
|
||||
});
|
||||
}
|
||||
else if(template.type && template.type === 'workflow_job_template') {
|
||||
TemplateCopyService.getWorkflowCopy(template.id)
|
||||
.then(function(result) {
|
||||
|
||||
if(result.data.can_copy) {
|
||||
if(!result.data.warnings || _.isEmpty(result.data.warnings)) {
|
||||
// Go ahead and copy the workflow - the user has full priveleges on all the resources
|
||||
TemplateCopyService.copyWorkflow(template.id)
|
||||
.then(function(result) {
|
||||
$state.go('templates.editWorkflowJobTemplate', {workflow_job_template_id: result.data.id}, {reload: true});
|
||||
}, function (data) {
|
||||
Wait('stop');
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to copy template failed. POST returned status: ' + status });
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
let bodyHtml = `
|
||||
<div class="Prompt-bodyQuery">
|
||||
You may not have access to all resources used by this workflow. Resources that you don\'t have access to will not be copied and may result in an incomplete workflow.
|
||||
</div>
|
||||
<div class="Prompt-bodyTarget">`;
|
||||
|
||||
// Go and grab all of the warning strings
|
||||
_.forOwn(result.data.warnings, function(warning) {
|
||||
if(warning) {
|
||||
_.forOwn(warning, function(warningString) {
|
||||
bodyHtml += '<div>' + warningString + '</div>';
|
||||
});
|
||||
}
|
||||
} );
|
||||
|
||||
bodyHtml += '</div>';
|
||||
|
||||
|
||||
Prompt({
|
||||
hdr: 'Copy Workflow',
|
||||
body: bodyHtml,
|
||||
action: function() {
|
||||
$('#prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
TemplateCopyService.copyWorkflow(template.id)
|
||||
.then(function(result) {
|
||||
Wait('stop');
|
||||
$state.go('templates.editWorkflowJobTemplate', {workflow_job_template_id: result.data.id}, {reload: true});
|
||||
}, function (data) {
|
||||
Wait('stop');
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to copy template failed. POST returned status: ' + status });
|
||||
});
|
||||
},
|
||||
actionText: 'COPY',
|
||||
class: 'Modal-primaryButton'
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
Alert('Error: Unable to copy workflow job template', 'You do not have permission to perform this action.');
|
||||
}
|
||||
}, function (data) {
|
||||
Wait('stop');
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to copy template failed. GET returned status: ' + status });
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Something went wrong - Let the user know that we're unable to copy because we don't know
|
||||
// what type of job template this is
|
||||
Alert('Error: Unable to determine template type', 'We were unable to determine this template\'s type while copying.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
Alert('Error: Unable to copy job', 'Template parameter is missing');
|
||||
}
|
||||
};
|
||||
}
|
||||
];
|
||||
|
@ -9,7 +9,6 @@ import surveyMaker from './survey-maker/main';
|
||||
import templatesList from './list/main';
|
||||
import jobTemplatesAdd from './job_templates/add-job-template/main';
|
||||
import jobTemplatesEdit from './job_templates/edit-job-template/main';
|
||||
import jobTemplatesCopy from './job_templates/copy-job-template/main';
|
||||
import workflowAdd from './workflows/add-workflow/main';
|
||||
import workflowEdit from './workflows/edit-workflow/main';
|
||||
import labels from './labels/main';
|
||||
@ -17,14 +16,16 @@ import workflowChart from './workflows/workflow-chart/main';
|
||||
import workflowMaker from './workflows/workflow-maker/main';
|
||||
import templatesListRoute from './list/templates-list.route';
|
||||
import workflowService from './workflows/workflow.service';
|
||||
import templateCopyService from './copy-template/template-copy.service';
|
||||
|
||||
export default
|
||||
angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesAdd.name,
|
||||
jobTemplatesEdit.name, jobTemplatesCopy.name, labels.name, workflowAdd.name, workflowEdit.name,
|
||||
jobTemplatesEdit.name, labels.name, workflowAdd.name, workflowEdit.name,
|
||||
workflowChart.name, workflowMaker.name
|
||||
])
|
||||
.service('TemplatesService', templatesService)
|
||||
.service('WorkflowService', workflowService)
|
||||
.service('TemplateCopyService', templateCopyService)
|
||||
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
|
||||
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
|
||||
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,
|
||||
|
@ -185,6 +185,22 @@ export default ['Rest', 'GetBasePath', '$q', function(Rest, GetBasePath, $q){
|
||||
|
||||
Rest.setUrl(url);
|
||||
return Rest.get();
|
||||
},
|
||||
getWorkflowCopy: function(id) {
|
||||
let url = GetBasePath('workflow_job_templates');
|
||||
|
||||
url = url + id + '/copy';
|
||||
|
||||
Rest.setUrl(url);
|
||||
return Rest.get();
|
||||
},
|
||||
copyWorkflow: function(id) {
|
||||
let url = GetBasePath('workflow_job_templates');
|
||||
|
||||
url = url + id + '/copy';
|
||||
|
||||
Rest.setUrl(url);
|
||||
return Rest.post();
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
Loading…
Reference in New Issue
Block a user