mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
Implemented WFJT copy and moved JT copy away from a viewless route
This commit is contained in:
parent
5cf0b8929f
commit
089f369cc4
@ -27,21 +27,21 @@ export default
|
|||||||
first_name: {
|
first_name: {
|
||||||
label: i18n._('First Name'),
|
label: i18n._('First Name'),
|
||||||
type: 'text',
|
type: 'text',
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)',
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
required: true,
|
required: true,
|
||||||
capitalize: true
|
capitalize: true
|
||||||
},
|
},
|
||||||
last_name: {
|
last_name: {
|
||||||
label: i18n._('Last Name'),
|
label: i18n._('Last Name'),
|
||||||
type: 'text',
|
type: 'text',
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)',
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
required: true,
|
required: true,
|
||||||
capitalize: true
|
capitalize: true
|
||||||
},
|
},
|
||||||
email: {
|
email: {
|
||||||
label: i18n._('Email'),
|
label: i18n._('Email'),
|
||||||
type: 'email',
|
type: 'email',
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)',
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
required: true,
|
required: true,
|
||||||
autocomplete: false
|
autocomplete: false
|
||||||
},
|
},
|
||||||
@ -53,7 +53,7 @@ export default
|
|||||||
init: true
|
init: true
|
||||||
},
|
},
|
||||||
autocomplete: false,
|
autocomplete: false,
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
organization: {
|
organization: {
|
||||||
label: i18n._('Organization'),
|
label: i18n._('Organization'),
|
||||||
@ -64,7 +64,7 @@ export default
|
|||||||
sourceField: 'name',
|
sourceField: 'name',
|
||||||
required: true,
|
required: true,
|
||||||
excludeMode: 'edit',
|
excludeMode: 'edit',
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
label: i18n._('Password'),
|
label: i18n._('Password'),
|
||||||
@ -76,7 +76,7 @@ export default
|
|||||||
ngChange: "clearPWConfirm('password_confirm')",
|
ngChange: "clearPWConfirm('password_confirm')",
|
||||||
autocomplete: false,
|
autocomplete: false,
|
||||||
chkPass: true,
|
chkPass: true,
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
password_confirm: {
|
password_confirm: {
|
||||||
label: i18n._('Confirm Password'),
|
label: i18n._('Confirm Password'),
|
||||||
@ -88,7 +88,7 @@ export default
|
|||||||
awPassMatch: true,
|
awPassMatch: true,
|
||||||
associated: 'password',
|
associated: 'password',
|
||||||
autocomplete: false,
|
autocomplete: false,
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
user_type: {
|
user_type: {
|
||||||
label: i18n._('User Type'),
|
label: i18n._('User Type'),
|
||||||
@ -97,23 +97,23 @@ export default
|
|||||||
disableChooseOption: true,
|
disableChooseOption: true,
|
||||||
ngModel: 'user_type',
|
ngModel: 'user_type',
|
||||||
ngShow: 'current_user["is_superuser"]',
|
ngShow: 'current_user["is_superuser"]',
|
||||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
buttons: {
|
buttons: {
|
||||||
cancel: {
|
cancel: {
|
||||||
ngClick: 'formCancel()',
|
ngClick: 'formCancel()',
|
||||||
ngShow: '(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngShow: '(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
close: {
|
close: {
|
||||||
ngClick: 'formCancel()',
|
ngClick: 'formCancel()',
|
||||||
ngShow: '!(user_obj.summary_fields.user_capabilities.edit || !canAdd)'
|
ngShow: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
},
|
},
|
||||||
save: {
|
save: {
|
||||||
ngClick: 'formSave()',
|
ngClick: 'formSave()',
|
||||||
ngDisabled: true,
|
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: {
|
copy: {
|
||||||
label: i18n._('Copy'),
|
label: i18n._('Copy'),
|
||||||
'ui-sref': 'templates.copy({id: template.id})',
|
ngClick: 'copyTemplate(template)',
|
||||||
"class": 'btn-danger btn-xs',
|
"class": 'btn-danger btn-xs',
|
||||||
awToolTip: i18n._('Copy template'),
|
awToolTip: i18n._('Copy template'),
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
|
@ -99,6 +99,21 @@
|
|||||||
color: @btn-txt-sel;
|
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 {
|
.Modal-errorButton:focus {
|
||||||
color: @btn-txt-sel;
|
color: @btn-txt-sel;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ angular.module('PromptDialog', ['Utilities', 'sanitizeFilter'])
|
|||||||
|
|
||||||
cls = (params['class'] === null || params['class'] === undefined) ? 'Modal-errorButton' : params['class'];
|
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
|
// 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
|
// 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])
|
return Rest.post(data.results[0])
|
||||||
.success(function(job_template_res){
|
.success(function(job_template_res){
|
||||||
// also copy any associated survey_spec
|
// 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);
|
return self.copySurvey(data.results[0], job_template_res).success( () => job_template_res);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -54,6 +54,22 @@
|
|||||||
buildName: function(name){
|
buildName: function(name){
|
||||||
var result = name.split('@')[0];
|
var result = name.split('@')[0];
|
||||||
return result;
|
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',
|
export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Alert',
|
||||||
'TemplateList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
|
'TemplateList', 'Prompt', 'ClearScope', 'ProcessErrors', 'GetBasePath',
|
||||||
'InitiatePlaybookRun', 'Wait', '$state', '$filter', 'Dataset', 'rbacUiControlService', 'TemplatesService',
|
'InitiatePlaybookRun', 'Wait', '$state', '$filter', 'Dataset', 'rbacUiControlService', 'TemplatesService',
|
||||||
'QuerySet', 'GetChoices',
|
'QuerySet', 'GetChoices', 'TemplateCopyService',
|
||||||
function(
|
function(
|
||||||
$scope, $rootScope, $location, $stateParams, Rest, Alert,
|
$scope, $rootScope, $location, $stateParams, Rest, Alert,
|
||||||
TemplateList, Prompt, ClearScope, ProcessErrors, GetBasePath,
|
TemplateList, Prompt, ClearScope, ProcessErrors, GetBasePath,
|
||||||
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, TemplatesService,
|
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, TemplatesService,
|
||||||
qs, GetChoices
|
qs, GetChoices, TemplateCopyService
|
||||||
) {
|
) {
|
||||||
ClearScope();
|
ClearScope();
|
||||||
|
|
||||||
@ -192,5 +192,101 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', 'Al
|
|||||||
Alert('Error: Unable to schedule job', 'Template parameter is missing');
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -17,6 +17,7 @@ import workflowChart from './workflows/workflow-chart/main';
|
|||||||
import workflowMaker from './workflows/workflow-maker/main';
|
import workflowMaker from './workflows/workflow-maker/main';
|
||||||
import templatesListRoute from './list/templates-list.route';
|
import templatesListRoute from './list/templates-list.route';
|
||||||
import workflowService from './workflows/workflow.service';
|
import workflowService from './workflows/workflow.service';
|
||||||
|
import templateCopyService from './copy-template/templay-copy.service';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesAdd.name,
|
angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesAdd.name,
|
||||||
@ -25,6 +26,7 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA
|
|||||||
])
|
])
|
||||||
.service('TemplatesService', templatesService)
|
.service('TemplatesService', templatesService)
|
||||||
.service('WorkflowService', workflowService)
|
.service('WorkflowService', workflowService)
|
||||||
|
.service('TemplateCopyService', templateCopyService)
|
||||||
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
|
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
|
||||||
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
|
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
|
||||||
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,
|
let stateTree, addJobTemplate, editJobTemplate, addWorkflow, editWorkflow,
|
||||||
|
@ -185,6 +185,22 @@ export default ['Rest', 'GetBasePath', '$q', function(Rest, GetBasePath, $q){
|
|||||||
|
|
||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
return Rest.get();
|
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