Pass job into the relaunch component rather than pull it from the parent. Added launch template component, use it on the templates lists.

This commit is contained in:
mabashian
2018-03-22 16:14:17 -04:00
parent 8d04be0fc8
commit 7a4bc233f6
18 changed files with 236 additions and 387 deletions

View File

@@ -18,7 +18,6 @@ function ListTemplatesController(
Dataset, Dataset,
ProcessErrors, ProcessErrors,
Prompt, Prompt,
PromptService,
resolvedModels, resolvedModels,
strings, strings,
Wait Wait
@@ -68,21 +67,6 @@ function ListTemplatesController(
} }
}; };
vm.runTemplate = template => {
if (!template) {
Alert(strings.get('error.LAUNCH'), strings.get('alert.MISSING_PARAMETER'));
return;
}
if (isJobTemplate(template)) {
runJobTemplate(template);
} else if (isWorkflowTemplate(template)) {
runWorkflowTemplate(template);
} else {
Alert(strings.get('error.UNKNOWN'), strings.get('alert.UNKNOWN_LAUNCH'));
}
};
vm.scheduleTemplate = template => { vm.scheduleTemplate = template => {
if (!template) { if (!template) {
Alert(strings.get('error.SCHEDULE'), strings.get('alert.MISSING_PARAMETER')); Alert(strings.get('error.SCHEDULE'), strings.get('alert.MISSING_PARAMETER'));
@@ -323,120 +307,6 @@ function ListTemplatesController(
return html; return html;
} }
function runJobTemplate(template) {
const selectedJobTemplate = jobTemplate.create();
const preLaunchPromises = [
selectedJobTemplate.getLaunch(template.id),
selectedJobTemplate.optionsLaunch(template.id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedJobTemplate.canLaunchWithoutPrompt()) {
return selectedJobTemplate
.postLaunch({ id: template.id })
.then(({ data }) => {
$state.go('jobResult', { id: data.job }, { reload: true });
});
}
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: template.id,
templateType: template.type,
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedJobTemplate.getSurveyQuestions(template.id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({ surveyQuestions: data.spec });
promptData.surveyQuestions = processed.surveyQuestions;
$scope.promptData = promptData;
});
} else {
$scope.promptData = promptData;
}
});
}
function runWorkflowTemplate(template) {
const selectedWorkflowJobTemplate = workflowTemplate.create();
const preLaunchPromises = [
selectedWorkflowJobTemplate.getLaunch(template.id),
selectedWorkflowJobTemplate.optionsLaunch(template.id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedWorkflowJobTemplate.canLaunchWithoutPrompt()) {
return selectedWorkflowJobTemplate
.postLaunch({ id: template.id })
.then(({ data }) => {
$state.go('workflowResults', { id: data.workflow_job }, { reload: true });
});
}
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: template.id,
templateType: template.type,
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedWorkflowJobTemplate.getSurveyQuestions(template.id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({ surveyQuestions: data.spec });
promptData.surveyQuestions = processed.surveyQuestions;
$scope.promptData = promptData;
});
} else {
$scope.promptData = promptData;
}
});
}
$scope.launchJob = () => {
const jobLaunchData = PromptService.bundlePromptDataForLaunch($scope.promptData);
// If the extra_vars dict is empty, we don't want to include it if we didn't prompt for anything.
if(_.isEmpty(jobLaunchData.extra_vars) && !($scope.promptData.launchConf.ask_variables_on_launch && $scope.promptData.launchConf.survey_enabled && $scope.promptData.surveyQuestions.length > 0)){
delete jobLaunchData.extra_vars;
}
if($scope.promptData.templateType === 'job_template') {
jobTemplate.create().postLaunch({
id: $scope.promptData.template,
launchData: jobLaunchData
})
.then((launchRes) => {
$state.go('jobResult', { id: launchRes.data.job }, { reload: true });
})
.catch(createErrorHandler('launch job template', 'POST'));
} else if($scope.promptData.templateType === 'workflow_job_template') {
workflowTemplate.create().postLaunch({
id: $scope.promptData.template,
launchData: jobLaunchData
})
.then((launchRes) => {
$state.go('workflowResults', { id: launchRes.data.workflow_job }, { reload: true });
})
.catch(createErrorHandler('launch workflow job template', 'POST'));
}
};
} }
ListTemplatesController.$inject = [ ListTemplatesController.$inject = [
@@ -447,7 +317,6 @@ ListTemplatesController.$inject = [
'Dataset', 'Dataset',
'ProcessErrors', 'ProcessErrors',
'Prompt', 'Prompt',
'PromptService',
'resolvedModels', 'resolvedModels',
'TemplatesStrings', 'TemplatesStrings',
'Wait' 'Wait'

View File

@@ -61,7 +61,7 @@ export default {
Wait('start'); Wait('start');
return qs.search(searchPath, searchParam) return qs.search(searchPath, searchParam)
.finally(() => Wait('stop')) .finally(() => Wait('stop'));
} }
], ],
} }

View File

@@ -98,9 +98,9 @@
</labels-list> </labels-list>
</div> </div>
<div class="at-Row-actions"> <div class="at-Row-actions">
<at-row-action icon="icon-launch" ng-click="vm.runTemplate(template)" <at-launch-template template="template"
ng-show="template.summary_fields.user_capabilities.start"> ng-show="template.summary_fields.user_capabilities.start">
</at-row-action> </at-launch-template>
<at-row-action icon="fa-calendar" ng-click="vm.scheduleTemplate(template)" <at-row-action icon="fa-calendar" ng-click="vm.scheduleTemplate(template)"
ng-show="template.summary_fields.user_capabilities.schedule"> ng-show="template.summary_fields.user_capabilities.schedule">
</at-row-action> </at-row-action>
@@ -121,5 +121,4 @@
query-set="querySet"> query-set="querySet">
</paginate> </paginate>
</at-panel-body> </at-panel-body>
<prompt prompt-data="promptData" on-finish="launchJob()"></launch>
</at-panel> </at-panel>

View File

@@ -1,11 +1,12 @@
@import 'action/_index'; @import 'action/_index';
@import 'input/_index'; @import 'input/_index';
@import 'launchTemplateButton/_index';
@import 'layout/_index'; @import 'layout/_index';
@import 'list/_index'; @import 'list/_index';
@import 'modal/_index'; @import 'modal/_index';
@import 'panel/_index'; @import 'panel/_index';
@import 'popover/_index'; @import 'popover/_index';
@import 'tabs/_index';
@import 'utility/_index';
@import 'truncate/_index';
@import 'relaunchButton/_index'; @import 'relaunchButton/_index';
@import 'tabs/_index';
@import 'truncate/_index';
@import 'utility/_index';

View File

@@ -16,23 +16,24 @@ import inputSlider from '~components/input/slider.directive';
import inputText from '~components/input/text.directive'; import inputText from '~components/input/text.directive';
import inputTextarea from '~components/input/textarea.directive'; import inputTextarea from '~components/input/textarea.directive';
import inputTextareaSecret from '~components/input/textarea-secret.directive'; import inputTextareaSecret from '~components/input/textarea-secret.directive';
import launchTemplate from '~components/launchTemplateButton/launchTemplateButton.component';
import layout from '~components/layout/layout.directive'; import layout from '~components/layout/layout.directive';
import list from '~components/list/list.directive'; import list from '~components/list/list.directive';
import row from '~components/list/row.directive';
import rowItem from '~components/list/row-item.directive';
import rowAction from '~components/list/row-action.directive';
import modal from '~components/modal/modal.directive'; import modal from '~components/modal/modal.directive';
import panel from '~components/panel/panel.directive'; import panel from '~components/panel/panel.directive';
import panelBody from '~components/panel/body.directive'; import panelBody from '~components/panel/body.directive';
import panelHeading from '~components/panel/heading.directive'; import panelHeading from '~components/panel/heading.directive';
import popover from '~components/popover/popover.directive'; import popover from '~components/popover/popover.directive';
import relaunch from '~components/relaunchButton/relaunchButton.component';
import row from '~components/list/row.directive';
import rowItem from '~components/list/row-item.directive';
import rowAction from '~components/list/row-action.directive';
import sideNav from '~components/layout/side-nav.directive'; import sideNav from '~components/layout/side-nav.directive';
import sideNavItem from '~components/layout/side-nav-item.directive'; import sideNavItem from '~components/layout/side-nav-item.directive';
import tab from '~components/tabs/tab.directive'; import tab from '~components/tabs/tab.directive';
import tabGroup from '~components/tabs/group.directive'; import tabGroup from '~components/tabs/group.directive';
import topNavItem from '~components/layout/top-nav-item.directive'; import topNavItem from '~components/layout/top-nav-item.directive';
import truncate from '~components/truncate/truncate.directive'; import truncate from '~components/truncate/truncate.directive';
import relaunch from '~components/relaunchButton/relaunchButton.component';
import BaseInputController from '~components/input/base.controller'; import BaseInputController from '~components/input/base.controller';
import ComponentsStrings from '~components/components.strings'; import ComponentsStrings from '~components/components.strings';
@@ -59,8 +60,10 @@ angular
.directive('atInputText', inputText) .directive('atInputText', inputText)
.directive('atInputTextarea', inputTextarea) .directive('atInputTextarea', inputTextarea)
.directive('atInputTextareaSecret', inputTextareaSecret) .directive('atInputTextareaSecret', inputTextareaSecret)
.component('atLaunchTemplate', launchTemplate)
.directive('atLayout', layout) .directive('atLayout', layout)
.directive('atList', list) .directive('atList', list)
.component('atRelaunch', relaunch)
.directive('atRow', row) .directive('atRow', row)
.directive('atRowItem', rowItem) .directive('atRowItem', rowItem)
.directive('atRowAction', rowAction) .directive('atRowAction', rowAction)
@@ -75,7 +78,6 @@ angular
.directive('atTabGroup', tabGroup) .directive('atTabGroup', tabGroup)
.directive('atTopNavItem', topNavItem) .directive('atTopNavItem', topNavItem)
.directive('atTruncate', truncate) .directive('atTruncate', truncate)
.component('atRelaunch', relaunch)
.service('BaseInputController', BaseInputController) .service('BaseInputController', BaseInputController)
.service('ComponentsStrings', ComponentsStrings); .service('ComponentsStrings', ComponentsStrings);

View File

@@ -0,0 +1,24 @@
.at-LaunchTemplate {
margin-left: 15px;
&--button {
font-size: 16px;
height: 30px;
min-width: 30px;
color: #848992;
background-color: inherit;
border: none;
border-radius: 4px;
}
&--button:hover {
background-color: @at-blue;
color: white;
}
}
.open {
.at-LaunchTemplate--button {
background-color: @at-blue;
color: white;
}
}

View File

@@ -0,0 +1,152 @@
import templateUrl from './launchTemplateButton.partial.html';
const atLaunchTemplate = {
templateUrl,
bindings: {
template: '<'
},
controller: ['JobTemplateModel', 'WorkflowJobTemplateModel', 'PromptService', '$state',
'ProcessErrors', '$scope', 'TemplatesStrings', 'Alert', atLaunchTemplateCtrl],
controllerAs: 'vm'
};
function atLaunchTemplateCtrl (
JobTemplate, WorkflowTemplate, PromptService, $state,
ProcessErrors, $scope, strings, Alert
) {
const vm = this;
const jobTemplate = new JobTemplate();
const workflowTemplate = new WorkflowTemplate();
const createErrorHandler = (path, action) =>
({ data, status }) => {
const hdr = strings.get('error.HEADER');
const msg = strings.get('error.CALL', { path, action, status });
ProcessErrors($scope, data, status, null, { hdr, msg });
};
vm.startLaunchTemplate = () => {
if (vm.template.type === 'job_template') {
const selectedJobTemplate = jobTemplate.create();
const preLaunchPromises = [
selectedJobTemplate.getLaunch(vm.template.id),
selectedJobTemplate.optionsLaunch(vm.template.id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedJobTemplate.canLaunchWithoutPrompt()) {
selectedJobTemplate
.postLaunch({ id: vm.template.id })
.then(({ data }) => {
$state.go('jobResult', { id: data.job }, { reload: true });
});
} else {
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: vm.template.id,
templateType: vm.template.type,
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedJobTemplate.getSurveyQuestions(vm.template.id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({
surveyQuestions: data.spec
});
promptData.surveyQuestions = processed.surveyQuestions;
vm.promptData = promptData;
});
} else {
vm.promptData = promptData;
}
}
});
} else if (vm.template.type === 'workflow_job_template') {
const selectedWorkflowJobTemplate = workflowTemplate.create();
const preLaunchPromises = [
selectedWorkflowJobTemplate.getLaunch(vm.template.id),
selectedWorkflowJobTemplate.optionsLaunch(vm.template.id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedWorkflowJobTemplate.canLaunchWithoutPrompt()) {
selectedWorkflowJobTemplate
.postLaunch({ id: vm.template.id })
.then(({ data }) => {
$state.go('workflowResults', { id: data.workflow_job }, { reload: true });
});
} else {
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: vm.template.id,
templateType: vm.template.type,
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedWorkflowJobTemplate.getSurveyQuestions(vm.template.id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({
surveyQuestions: data.spec
});
promptData.surveyQuestions = processed.surveyQuestions;
vm.promptData = promptData;
});
} else {
vm.promptData = promptData;
}
}
});
} else {
Alert(strings.get('error.UNKNOWN'), strings.get('alert.UNKNOWN_LAUNCH'));
}
};
vm.launchTemplateWithPrompts = () => {
const jobLaunchData = PromptService.bundlePromptDataForLaunch(vm.promptData);
// If the extra_vars dict is empty, we don't want to include it
// if we didn't prompt for anything.
if (
_.isEmpty(jobLaunchData.extra_vars) &&
!(
vm.promptData.launchConf.ask_variables_on_launch &&
vm.promptData.launchConf.survey_enabled &&
vm.promptData.surveyQuestions.length > 0
)
) {
delete jobLaunchData.extra_vars;
}
if (vm.promptData.templateType === 'job_template') {
jobTemplate.create().postLaunch({
id: vm.promptData.template,
launchData: jobLaunchData
}).then((launchRes) => {
$state.go('jobResult', { id: launchRes.data.job }, { reload: true });
}).catch(createErrorHandler('launch job template', 'POST'));
} else if (vm.promptData.templateType === 'workflow_job_template') {
workflowTemplate.create().postLaunch({
id: vm.promptData.template,
launchData: jobLaunchData
}).then((launchRes) => {
$state.go('workflowResults', { id: launchRes.data.workflow_job }, { reload: true });
}).catch(createErrorHandler('launch workflow job template', 'POST'));
}
};
}
export default atLaunchTemplate;

View File

@@ -0,0 +1,7 @@
<div class="at-LaunchTemplate">
<button class="at-LaunchTemplate--button"
ng-click="vm.startLaunchTemplate()">
<i class="icon-launch"></i>
</button>
<prompt prompt-data="vm.promptData" on-finish="vm.launchTemplateWithPrompts()"></launch>
</div>

View File

@@ -3,12 +3,12 @@ import templateUrl from './relaunchButton.partial.html';
const atRelaunch = { const atRelaunch = {
templateUrl, templateUrl,
bindings: { bindings: {
state: '<' job: '<'
}, },
controller: ['ProcessErrors', 'AdhocRun', 'ComponentsStrings', controller: ['ProcessErrors', 'AdhocRun', 'ComponentsStrings',
'ProjectModel', 'InventorySourceModel', 'WorkflowJobModel', 'Alert', 'ProjectModel', 'InventorySourceModel', 'WorkflowJobModel', 'Alert',
'AdHocCommandModel', 'JobModel', 'JobTemplateModel', 'PromptService', 'AdHocCommandModel', 'JobModel', 'JobTemplateModel', 'PromptService',
'GetBasePath', '$state', '$q', '$scope', atRelaunchCtrl '$state', '$q', '$scope', atRelaunchCtrl
], ],
controllerAs: 'vm' controllerAs: 'vm'
}; };
@@ -17,25 +17,23 @@ function atRelaunchCtrl (
ProcessErrors, AdhocRun, strings, ProcessErrors, AdhocRun, strings,
Project, InventorySource, WorkflowJob, Alert, Project, InventorySource, WorkflowJob, Alert,
AdHocCommand, Job, JobTemplate, PromptService, AdHocCommand, Job, JobTemplate, PromptService,
GetBasePath, $state, $q, $scope $state, $q, $scope
) { ) {
const vm = this; const vm = this;
const scope = $scope.$parent;
const job = _.get(scope, 'job') || _.get(scope, 'completed_job');
const jobObj = new Job(); const jobObj = new Job();
const jobTemplate = new JobTemplate(); const jobTemplate = new JobTemplate();
const checkRelaunchPlaybook = (option) => { const checkRelaunchPlaybook = (option) => {
jobObj.getRelaunch({ jobObj.getRelaunch({
id: job.id id: vm.job.id
}).then((getRelaunchRes) => { }).then((getRelaunchRes) => {
if ( if (
getRelaunchRes.data.passwords_needed_to_start && getRelaunchRes.data.passwords_needed_to_start &&
getRelaunchRes.data.passwords_needed_to_start.length > 0 getRelaunchRes.data.passwords_needed_to_start.length > 0
) { ) {
const jobPromises = [ const jobPromises = [
jobObj.request('get', job.id), jobObj.request('get', vm.job.id),
jobTemplate.optionsLaunch(job.unified_job_template) jobTemplate.optionsLaunch(vm.job.unified_job_template)
]; ];
$q.all(jobPromises) $q.all(jobPromises)
@@ -66,7 +64,7 @@ function atRelaunchCtrl (
getRelaunchRes.data.passwords_needed_to_start getRelaunchRes.data.passwords_needed_to_start
}, },
launchOptions: launchOptions.data, launchOptions: launchOptions.data,
job: job.id, job: vm.job.id,
relaunchHostType: option ? (option.name).toLowerCase() : null, relaunchHostType: option ? (option.name).toLowerCase() : null,
prompts: { prompts: {
credentials: { credentials: {
@@ -104,7 +102,7 @@ function atRelaunchCtrl (
}); });
} else { } else {
jobObj.postRelaunch({ jobObj.postRelaunch({
id: job.id id: vm.job.id
}).then((launchRes) => { }).then((launchRes) => {
if (!$state.includes('jobs')) { if (!$state.includes('jobs')) {
$state.go('jobResult', { id: launchRes.data.id }, { reload: true }); $state.go('jobResult', { id: launchRes.data.id }, { reload: true });
@@ -115,8 +113,8 @@ function atRelaunchCtrl (
}; };
vm.$onInit = () => { vm.$onInit = () => {
vm.showRelaunch = job.type !== 'system_job' && job.summary_fields.user_capabilities.start; vm.showRelaunch = vm.job.type !== 'system_job' && vm.job.summary_fields.user_capabilities.start;
vm.showDropdown = job.type === 'job' && job.failed === true; vm.showDropdown = vm.job.type === 'job' && vm.job.failed === true;
vm.createDropdown(); vm.createDropdown();
vm.createTooltips(); vm.createTooltips();
@@ -146,13 +144,13 @@ function atRelaunchCtrl (
}; };
vm.relaunchJob = () => { vm.relaunchJob = () => {
if (job.type === 'inventory_update') { if (vm.job.type === 'inventory_update') {
const inventorySource = new InventorySource(); const inventorySource = new InventorySource();
inventorySource.getUpdate(job.inventory_source) inventorySource.getUpdate(vm.job.inventory_source)
.then((getUpdateRes) => { .then((getUpdateRes) => {
if (getUpdateRes.data.can_update) { if (getUpdateRes.data.can_update) {
inventorySource.postUpdate(job.inventory_source) inventorySource.postUpdate(vm.job.inventory_source)
.then((postUpdateRes) => { .then((postUpdateRes) => {
if (!$state.includes('jobs')) { if (!$state.includes('jobs')) {
$state.go('inventorySyncStdout', { id: postUpdateRes.data.id }, { reload: true }); $state.go('inventorySyncStdout', { id: postUpdateRes.data.id }, { reload: true });
@@ -165,13 +163,13 @@ function atRelaunchCtrl (
); );
} }
}); });
} else if (job.type === 'project_update') { } else if (vm.job.type === 'project_update') {
const project = new Project(); const project = new Project();
project.getUpdate(job.project) project.getUpdate(vm.job.project)
.then((getUpdateRes) => { .then((getUpdateRes) => {
if (getUpdateRes.data.can_update) { if (getUpdateRes.data.can_update) {
project.postUpdate(job.project) project.postUpdate(vm.job.project)
.then((postUpdateRes) => { .then((postUpdateRes) => {
if (!$state.includes('jobs')) { if (!$state.includes('jobs')) {
$state.go('scmUpdateStdout', { id: postUpdateRes.data.id }, { reload: true }); $state.go('scmUpdateStdout', { id: postUpdateRes.data.id }, { reload: true });
@@ -184,30 +182,30 @@ function atRelaunchCtrl (
); );
} }
}); });
} else if (job.type === 'workflow_job') { } else if (vm.job.type === 'workflow_job') {
const workflowJob = new WorkflowJob(); const workflowJob = new WorkflowJob();
workflowJob.postRelaunch({ workflowJob.postRelaunch({
id: job.id id: vm.job.id
}).then((launchRes) => { }).then((launchRes) => {
if (!$state.includes('jobs')) { if (!$state.includes('jobs')) {
$state.go('workflowResults', { id: launchRes.data.id }, { reload: true }); $state.go('workflowResults', { id: launchRes.data.id }, { reload: true });
} }
}); });
} else if (job.type === 'ad_hoc_command') { } else if (vm.job.type === 'ad_hoc_command') {
const adHocCommand = new AdHocCommand(); const adHocCommand = new AdHocCommand();
adHocCommand.getRelaunch({ adHocCommand.getRelaunch({
id: job.id id: vm.job.id
}).then((getRelaunchRes) => { }).then((getRelaunchRes) => {
if ( if (
getRelaunchRes.data.passwords_needed_to_start && getRelaunchRes.data.passwords_needed_to_start &&
getRelaunchRes.data.passwords_needed_to_start.length > 0 getRelaunchRes.data.passwords_needed_to_start.length > 0
) { ) {
AdhocRun({ scope, project_id: job.id, relaunch: true }); AdhocRun({ scope: $scope, project_id: vm.job.id, relaunch: true });
} else { } else {
adHocCommand.postRelaunch({ adHocCommand.postRelaunch({
id: job.id id: vm.job.id
}).then((launchRes) => { }).then((launchRes) => {
if (!$state.includes('jobs')) { if (!$state.includes('jobs')) {
$state.go('adHocJobStdout', { id: launchRes.data.id }, { reload: true }); $state.go('adHocJobStdout', { id: launchRes.data.id }, { reload: true });
@@ -215,7 +213,7 @@ function atRelaunchCtrl (
}); });
} }
}); });
} else if (job.type === 'job') { } else if (vm.job.type === 'job') {
checkRelaunchPlaybook(); checkRelaunchPlaybook();
} }
}; };

View File

@@ -2,12 +2,7 @@
export default export default
[ 'templateUrl', [ 'templateUrl',
'$state', '$state',
'Alert', function JobTemplatesList(templateUrl, $state) {
'JobTemplateModel',
'WorkflowJobTemplateModel',
'PromptService',
'ProcessErrors',
function JobTemplatesList(templateUrl, $state, Alert, JobTemplate, WorkflowJobTemplate, PromptService, ProcessErrors) {
return { return {
restrict: 'E', restrict: 'E',
link: link, link: link,
@@ -18,8 +13,6 @@ export default
}; };
function link(scope, element, attr) { function link(scope, element, attr) {
const jobTemplate = new JobTemplate();
const workflowTemplate = new WorkflowJobTemplate();
scope.$watch("data", function(data) { scope.$watch("data", function(data) {
if (data) { if (data) {
@@ -36,6 +29,7 @@ export default
// smartStatus?, launchUrl, editUrl, name // smartStatus?, launchUrl, editUrl, name
scope.templates = _.map(list, function(template){ return { scope.templates = _.map(list, function(template){ return {
recent_jobs: template.summary_fields.recent_jobs, recent_jobs: template.summary_fields.recent_jobs,
can_start: template.summary_fields.user_capabilities.start,
name: template.name, name: template.name,
id: template.id, id: template.id,
type: template.type type: template.type
@@ -46,135 +40,6 @@ export default
return (status === "successful"); return (status === "successful");
}; };
scope.launchTemplate = function(template){
if(template) {
if(template.type && (template.type === 'Job Template' || template.type === 'job_template')) {
const selectedJobTemplate = jobTemplate.create();
const preLaunchPromises = [
selectedJobTemplate.getLaunch(template.id),
selectedJobTemplate.optionsLaunch(template.id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedJobTemplate.canLaunchWithoutPrompt()) {
return selectedJobTemplate
.postLaunch({ id: template.id })
.then(({ data }) => {
$state.go('jobResult', { id: data.job }, { reload: true });
});
}
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: template.id,
templateType: template.type,
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedJobTemplate.getSurveyQuestions(template.id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({ surveyQuestions: data.spec });
promptData.surveyQuestions = processed.surveyQuestions;
scope.promptData = promptData;
});
} else {
scope.promptData = promptData;
}
});
}
else if(template.type && (template.type === 'Workflow Job Template' || template.type === 'workflow_job_template')) {
const selectedWorkflowJobTemplate = workflowTemplate.create();
const preLaunchPromises = [
selectedWorkflowJobTemplate.getLaunch(template.id),
selectedWorkflowJobTemplate.optionsLaunch(template.id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedWorkflowJobTemplate.canLaunchWithoutPrompt()) {
return selectedWorkflowJobTemplate
.postLaunch({ id: template.id })
.then(({ data }) => {
$state.go('workflowResults', { id: data.workflow_job }, { reload: true });
});
}
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: template.id,
templateType: template.type,
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedWorkflowJobTemplate.getSurveyQuestions(template.id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({ surveyQuestions: data.spec });
promptData.surveyQuestions = processed.surveyQuestions;
scope.promptData = promptData;
});
} else {
scope.promptData = promptData;
}
});
}
else {
// Something went wrong - Let the user know that we're unable to launch 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 launching.');
}
}
else {
Alert('Error: Unable to launch template', 'Template parameter is missing');
}
};
scope.launchJob = () => {
const jobLaunchData = PromptService.bundlePromptDataForLaunch(scope.promptData);
// If the extra_vars dict is empty, we don't want to include it if we didn't prompt for anything.
if(_.isEmpty(jobLaunchData.extra_vars) && !(scope.promptData.launchConf.ask_variables_on_launch && scope.promptData.launchConf.survey_enabled && scope.promptData.surveyQuestions.length > 0)){
delete jobLaunchData.extra_vars;
}
if(scope.promptData.templateType === 'job_template') {
jobTemplate.create().postLaunch({
id: scope.promptData.template,
launchData: jobLaunchData
})
.then((launchRes) => {
$state.go('jobResult', { id: launchRes.data.job }, { reload: true });
})
.catch(({data, status}) => {
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to launch job template: ' + status });
});
} else if(scope.promptData.templateType === 'workflow_job_template') {
workflowTemplate.create().postLaunch({
id: scope.promptData.template,
launchData: jobLaunchData
})
.then((launchRes) => {
$state.go('workflowResults', { id: launchRes.data.workflow_job }, { reload: true });
})
.catch(({data, status}) => {
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Failed to launch workflow job template: ' + status });
});
}
};
scope.editTemplate = function (template) { scope.editTemplate = function (template) {
if(template) { if(template) {
if(template.type && (template.type === 'Job Template' || template.type === 'job_template')) { if(template.type && (template.type === 'Job Template' || template.type === 'job_template')) {

View File

@@ -32,9 +32,9 @@
</td> </td>
<td class="List-actionsContainer"> <td class="List-actionsContainer">
<div class="List-actionButtonCell"> <div class="List-actionButtonCell">
<button class="List-actionButton" ng-click="launchTemplate(template)"> <at-launch-template template="template"
<i class="icon-launch"></i> ng-show="template.can_start">
</button> </at-launch-template>
<button class="List-actionButton" ng-click="editTemplate(template)"> <button class="List-actionButton" ng-click="editTemplate(template)">
<i class="fa fa-pencil"></i> <i class="fa fa-pencil"></i>
</button> </button>

View File

@@ -22,7 +22,7 @@
<div class="JobResults-panelHeaderButtonActions"> <div class="JobResults-panelHeaderButtonActions">
<!-- RELAUNCH ACTION --> <!-- RELAUNCH ACTION -->
<at-relaunch state="job"></at-relaunch> <at-relaunch job="job"></at-relaunch>
<!-- CANCEL ACTION --> <!-- CANCEL ACTION -->
<button class="List-actionButton <button class="List-actionButton

View File

@@ -33,11 +33,8 @@ export default ['i18n', function(i18n) {
fieldActions: { fieldActions: {
submit: { submit: {
label: i18n._('Launch'), // uses the at-launch-template directive
mode: 'all', launch: true
ngClick: 'submitJob(job_template.id)',
awToolTip: i18n._('Start a job using this template'),
dataPlacement: 'top'
} }
} }
};}]; };}];

View File

@@ -4,79 +4,12 @@
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
export function PortalModeJobTemplatesController($scope, PortalJobTemplateList, Dataset, $state, PromptService, JobTemplate, ProcessErrors) { export function PortalModeJobTemplatesController($scope, PortalJobTemplateList, Dataset) {
var list = PortalJobTemplateList; var list = PortalJobTemplateList;
// search init // search init
$scope.list = list; $scope.list = list;
$scope[`${list.iterator}_dataset`] = Dataset.data; $scope[`${list.iterator}_dataset`] = Dataset.data;
$scope[list.name] = $scope[`${list.iterator}_dataset`].results; $scope[list.name] = $scope[`${list.iterator}_dataset`].results;
const jobTemplate = new JobTemplate();
$scope.submitJob = function(id) {
const selectedJobTemplate = jobTemplate.create();
const preLaunchPromises = [
selectedJobTemplate.getLaunch(id),
selectedJobTemplate.optionsLaunch(id),
];
Promise.all(preLaunchPromises)
.then(([launchData, launchOptions]) => {
if (selectedJobTemplate.canLaunchWithoutPrompt()) {
return selectedJobTemplate
.postLaunch({ id: id })
.then(({ data }) => {
$state.go('jobResult', { id: data.job }, { reload: true });
});
}
const promptData = {
launchConf: launchData.data,
launchOptions: launchOptions.data,
template: id,
templateType: 'job_template',
prompts: PromptService.processPromptValues({
launchConf: launchData.data,
launchOptions: launchOptions.data
}),
triggerModalOpen: true,
};
if (launchData.data.survey_enabled) {
selectedJobTemplate.getSurveyQuestions(id)
.then(({ data }) => {
const processed = PromptService.processSurveyQuestions({ surveyQuestions: data.spec });
promptData.surveyQuestions = processed.surveyQuestions;
$scope.promptData = promptData;
});
} else {
$scope.promptData = promptData;
}
});
};
$scope.launchJob = () => {
const jobLaunchData = PromptService.bundlePromptDataForLaunch($scope.promptData);
// If the extra_vars dict is empty, we don't want to include it if we didn't prompt for anything.
if(_.isEmpty(jobLaunchData.extra_vars) && !($scope.promptData.launchConf.ask_variables_on_launch && $scope.promptData.launchConf.survey_enabled && $scope.promptData.surveyQuestions.length > 0)){
delete jobLaunchData.extra_vars;
}
jobTemplate.create().postLaunch({
id: $scope.promptData.template,
launchData: jobLaunchData
})
.then((launchRes) => {
$state.go('jobResult', { id: launchRes.data.job }, { reload: true });
})
.catch(({data, status}) => {
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to launch job template: ' + status });
});
};
} }
PortalModeJobTemplatesController.$inject = ['$scope','PortalJobTemplateList', 'job_templatesDataset', '$state', 'PromptService', 'JobTemplateModel', 'ProcessErrors']; PortalModeJobTemplatesController.$inject = ['$scope','PortalJobTemplateList', 'job_templatesDataset'];

View File

@@ -398,7 +398,9 @@ export default ['$compile', 'Attr', 'Icon',
} }
// Plug in Dropdown Component // Plug in Dropdown Component
if (field_action === 'submit' && list.fieldActions[field_action].relaunch === true) { if (field_action === 'submit' && list.fieldActions[field_action].relaunch === true) {
innerTable += `<at-relaunch></at-relaunch>`; innerTable += `<at-relaunch job="${list.iterator}"></at-relaunch>`;
} else if (field_action === 'submit' && list.fieldActions[field_action].launch === true) {
innerTable += `<at-launch-template template="${list.iterator}" ng-if="${list.iterator}.summary_fields.user_capabilities.start"></at-launch-template>`;
} else { } else {
fAction = list.fieldActions[field_action]; fAction = list.fieldActions[field_action];
innerTable += "<button id=\""; innerTable += "<button id=\"";

View File

@@ -9,7 +9,7 @@
</div> </div>
<div class="StandardOut-actions"> <div class="StandardOut-actions">
<div> <div>
<at-relaunch></at-relaunch> <at-relaunch job="job"></at-relaunch>
</div> </div>
<button id="cancel-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-show="job.status === 'waiting' || job.status === 'running' || job.status === 'pending'" aw-tool-tip="Cancel" data-original-title="" title=""><i class="fa fa-minus-circle"></i> </button> <button id="cancel-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-show="job.status === 'waiting' || job.status === 'running' || job.status === 'pending'" aw-tool-tip="Cancel" data-original-title="" title=""><i class="fa fa-minus-circle"></i> </button>
<button id="delete-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-hide="job.status === 'waiting' || job.status === 'running' || job.status === 'pending' " aw-tool-tip="Delete" data-original-title="" title=""><i class="fa fa-trash-o"></i> </button> <button id="delete-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-hide="job.status === 'waiting' || job.status === 'running' || job.status === 'pending' " aw-tool-tip="Delete" data-original-title="" title=""><i class="fa fa-trash-o"></i> </button>

View File

@@ -8,7 +8,7 @@
RESULTS RESULTS
</div> </div>
<div class="StandardOut-actions"> <div class="StandardOut-actions">
<at-relaunch></at-relaunch> <at-relaunch job="job"></at-relaunch>
<button id="cancel-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-show="job.status === 'waiting' || job.status === 'running' || job.status === 'pending'" aw-tool-tip="Cancel" data-original-title="" title=""><i class="fa fa-minus-circle"></i> </button> <button id="cancel-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-show="job.status === 'waiting' || job.status === 'running' || job.status === 'pending'" aw-tool-tip="Cancel" data-original-title="" title=""><i class="fa fa-minus-circle"></i> </button>
<button id="delete-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-hide="job.status === 'waiting' || job.status === 'running' || job.status === 'pending' " aw-tool-tip="Delete" data-original-title="" title=""><i class="fa fa-trash-o"></i> </button> <button id="delete-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-hide="job.status === 'waiting' || job.status === 'running' || job.status === 'pending' " aw-tool-tip="Delete" data-original-title="" title=""><i class="fa fa-trash-o"></i> </button>
</div> </div>

View File

@@ -8,7 +8,7 @@
RESULTS RESULTS
</div> </div>
<div class="StandardOut-actions"> <div class="StandardOut-actions">
<at-relaunch></at-relaunch> <at-relaunch job="job"></at-relaunch>
<button id="cancel-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-show="job.status === 'waiting' || job.status === 'running' || job.status === 'pending'" aw-tool-tip="{{'Cancel'|translate}}" data-original-title="" title=""><i class="fa fa-minus-circle"></i> </button> <button id="cancel-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-show="job.status === 'waiting' || job.status === 'running' || job.status === 'pending'" aw-tool-tip="{{'Cancel'|translate}}" data-original-title="" title=""><i class="fa fa-minus-circle"></i> </button>
<button id="delete-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-hide="job.status === 'waiting' || job.status === 'running' || job.status === 'pending' " aw-tool-tip="{{'Delete'|translate}}" data-original-title="" title=""><i class="fa fa-trash-o"></i> </button> <button id="delete-job-button" class="List-actionButton List-actionButton--delete jobResult-launchButton" data-placement="top" ng-click="deleteJob()" ng-hide="job.status === 'waiting' || job.status === 'running' || job.status === 'pending' " aw-tool-tip="{{'Delete'|translate}}" data-original-title="" title=""><i class="fa fa-trash-o"></i> </button>
</div> </div>