mirror of
https://github.com/ansible/awx.git
synced 2026-01-15 20:00:43 -03:30
initial details panel integration
This commit is contained in:
parent
a23e5e920f
commit
f65d170cab
502
awx/ui/client/features/output/details.directive.js
Normal file
502
awx/ui/client/features/output/details.directive.js
Normal file
@ -0,0 +1,502 @@
|
||||
const templateUrl = require('~features/output/details.partial.html');
|
||||
|
||||
let $http;
|
||||
let $filter;
|
||||
let $state;
|
||||
|
||||
let error;
|
||||
let parse;
|
||||
let prompt;
|
||||
let resource;
|
||||
let strings;
|
||||
let wait;
|
||||
|
||||
function mapChoices (choices) {
|
||||
return Object.assign(...choices.map(([k, v]) => ({[k]: v})));
|
||||
}
|
||||
|
||||
function getStatusDetails (status) {
|
||||
const value = status || resource.model.get('status');
|
||||
const label = 'Status';
|
||||
const choices = mapChoices(resource.model.options('actions.GET.status.choices'));
|
||||
|
||||
const displayValue = choices[value];
|
||||
|
||||
return { displayValue, label, value };
|
||||
}
|
||||
|
||||
function getStartTimeDetails (started) {
|
||||
const value = started || resource.model.get('started');
|
||||
const label = 'Started';
|
||||
|
||||
let displayValue;
|
||||
|
||||
if (value) {
|
||||
displayValue = $filter('longDate')(value);
|
||||
} else {
|
||||
displayValue = 'Not Started';
|
||||
}
|
||||
|
||||
return { displayValue, label, value };
|
||||
}
|
||||
|
||||
function getFinishTimeDetails (finished) {
|
||||
const value = finished || resource.model.get('finished');
|
||||
const label = 'Finished';
|
||||
|
||||
let displayValue;
|
||||
|
||||
if (value) {
|
||||
displayValue = $filter('longDate')(value);
|
||||
} else {
|
||||
displayValue = 'Not Finished';
|
||||
}
|
||||
|
||||
return { displayValue, label, value };
|
||||
}
|
||||
|
||||
function getJobTypeDetails () {
|
||||
const value = resource.model.get('job_type');
|
||||
const label = 'Job Type';
|
||||
const choices = mapChoices(resource.model.options('actions.GET.job_type.choices'));
|
||||
|
||||
const displayValue = choices[value];
|
||||
|
||||
return { displayValue, label, value };
|
||||
}
|
||||
|
||||
|
||||
function getVerbosityDetails () {
|
||||
const value = resource.model.get('verbosity');
|
||||
const choices = mapChoices(resource.model.options('actions.GET.verbosity.choices'));
|
||||
|
||||
const displayValue = choices[value];
|
||||
const label = 'Verbosity';
|
||||
|
||||
return { displayValue, label, value };
|
||||
}
|
||||
|
||||
function getSourceWorkflowJobDetails () {
|
||||
const sourceWorkflowJob = resource.model.get('summary_fields.source_workflow_job');
|
||||
|
||||
if (!sourceWorkflowJob) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const link = `/#/workflows/${sourceWorkflowJob.id}`;
|
||||
|
||||
return { link };
|
||||
}
|
||||
|
||||
function getJobTemplateDetails () {
|
||||
const jobTemplate = resource.model.get('summary_fields.job_template');
|
||||
|
||||
if (!jobTemplate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Job Template';
|
||||
const link = `/#/templates/job_template/${jobTemplate.id}`;
|
||||
const value = $filter('sanitize')(jobTemplate.name);
|
||||
|
||||
return { label, link, value };
|
||||
}
|
||||
|
||||
function getLaunchedByDetails () {
|
||||
const createdBy = resource.model.get('summary_fields.created_by');
|
||||
const jobTemplate = resource.model.get('summary_fields.job_template');
|
||||
|
||||
const relatedSchedule = resource.model.get('related.schedule');
|
||||
const schedule = resource.model.get('summary_fields.schedule');
|
||||
|
||||
if (!createdBy && !schedule) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Launched By';
|
||||
|
||||
let link;
|
||||
let tooltip;
|
||||
let value;
|
||||
|
||||
if (createdBy) {
|
||||
tooltip = 'Edit the User';
|
||||
link = `/#/users/${createdBy.id}`;
|
||||
value = $filter('sanitize')(createdBy.username);
|
||||
} else if (relatedSchedule && jobTemplate) {
|
||||
tooltip = 'Edit the Schedule';
|
||||
link = `/#/templates/job_template/${jobTemplate.id}/schedules/${schedule.id}`;
|
||||
value = $filter('sanitize')(schedule.name);
|
||||
} else {
|
||||
tooltip = null;
|
||||
link = null;
|
||||
value = $filter('sanitize')(schedule.name);
|
||||
}
|
||||
|
||||
return { label, link, tooltip, value };
|
||||
}
|
||||
|
||||
function getInventoryDetails () {
|
||||
const inventory = resource.model.get('summary_fields.inventory');
|
||||
|
||||
if (!inventory) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Inventory';
|
||||
const tooltip = 'Edit the inventory';
|
||||
const value = $filter('sanitize')(inventory.name);
|
||||
|
||||
let link;
|
||||
|
||||
if (inventory.kind === 'smart') {
|
||||
link = `/#/inventories/smart/${inventory.id}`;
|
||||
} else {
|
||||
link = `/#/inventories/inventory/${inventory.id}`;
|
||||
}
|
||||
|
||||
return { label, link, tooltip, value };
|
||||
}
|
||||
|
||||
function getProjectDetails () {
|
||||
const project = resource.model.get('summary_fields.project');
|
||||
const projectUpdate = resource.model.get('summary_fields.project_update');
|
||||
|
||||
if (!project) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Project';
|
||||
const link = `/#/projects/${project.id}`;
|
||||
const value = $filter('sanitize')(project.name);
|
||||
|
||||
if (projectUpdate) {
|
||||
const update = {
|
||||
link: `/#/jobz/project/${projectUpdate.id}`,
|
||||
tooltip: 'View project checkout results',
|
||||
status: projectUpdate.status,
|
||||
};
|
||||
|
||||
return { label, link, value, update };
|
||||
}
|
||||
|
||||
return { label, link, value };
|
||||
}
|
||||
|
||||
function getSCMRevisionDetails () {
|
||||
const label = 'Revision';
|
||||
const value = resource.model.get('scm_revision');
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getPlaybookDetails () {
|
||||
const label = 'Playbook';
|
||||
const value = resource.model.get('playbook');
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getJobExplanationDetails () {
|
||||
const jobExplanation = resource.model.get('job_explanation');
|
||||
|
||||
if (!jobExplanation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = null;
|
||||
|
||||
return { value };
|
||||
}
|
||||
|
||||
function getResultTracebackDetails () {
|
||||
const previousTaskFailed = false;
|
||||
const resultTraceback = resource.model.get('result_traceback');
|
||||
|
||||
if (!resultTraceback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!previousTaskFailed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Results Traceback';
|
||||
const value = null;
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getMachineCredentialDetails () {
|
||||
const machineCredential = resource.model.get('summary_fields.credential');
|
||||
|
||||
if (!machineCredential) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Machine Credential';
|
||||
const link = `/#/credentials/${machineCredential.id}`;
|
||||
const tooltip = 'Edit the Credential';
|
||||
const value = $filter('sanitize')(machineCredential.name);
|
||||
|
||||
return { label, link, tooltip, value };
|
||||
}
|
||||
|
||||
function getForkDetails () {
|
||||
const label = 'Forks';
|
||||
const value = resource.model.get('forks');
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getLimitDetails () {
|
||||
const label = 'Limit';
|
||||
const value = resource.model.get('limit');
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getInstanceGroupDetails () {
|
||||
|
||||
const instanceGroup = resource.model.get('summary_fields.instance_group');
|
||||
|
||||
if (!instanceGroup) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Instance Group';
|
||||
const value = $filter('sanitize')(instanceGroup.name);
|
||||
|
||||
let isolated = null;
|
||||
|
||||
if (instanceGroup.controller_id) {
|
||||
isolated = 'Isolated';
|
||||
}
|
||||
|
||||
return { label, value, isolated };
|
||||
}
|
||||
|
||||
function getJobTagDetails () {
|
||||
const label = 'Job Tags';
|
||||
const value = resource.model.get('job_tags');
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getSkipTagDetails () {
|
||||
const label = 'Skip Tags';
|
||||
const value = resource.model.get('skip_tags');
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { label, value };
|
||||
}
|
||||
|
||||
function getExtraVarsDetails () {
|
||||
const extraVars = resource.model.get('extra_vars');
|
||||
|
||||
if (!extraVars) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Extra Variables';
|
||||
const tooltip = 'Read-only view of extra variables added to the job template.';
|
||||
const value = parse(extraVars);
|
||||
|
||||
return { label, tooltip, value };
|
||||
}
|
||||
|
||||
function getLabelDetails () {
|
||||
const jobLabels = _.get(resource.model.get('related.labels'), 'results', []);
|
||||
|
||||
if (jobLabels.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = 'Labels';
|
||||
const value = jobLabels.map(({ name }) => name).map($filter('sanitize'));
|
||||
|
||||
let more = false;
|
||||
|
||||
return { label, more, value };
|
||||
}
|
||||
|
||||
function createErrorHandler (path, action) {
|
||||
return ({ data, status }) => {
|
||||
const hdr = strings.get('error.HEADER');
|
||||
const msg = strings.get('error.CALL', { path, action, status });
|
||||
|
||||
error($scope, data, status, null, { hdr, msg });
|
||||
};
|
||||
}
|
||||
|
||||
const ELEMENT_LABELS = '#job-results-labels';
|
||||
const ELEMENT_PROMPT_MODAL = '#prompt-modal';
|
||||
const LABELS_SLIDE_DISTANCE = 200;
|
||||
|
||||
function toggleLabels () {
|
||||
if (!this.labels.more) {
|
||||
$(ELEMENT_LABELS).slideUp(LABELS_SLIDE_DISTANCE);
|
||||
this.labels.more = true;
|
||||
} else {
|
||||
$(ELEMENT_LABELS).slideDown(LABELS_SLIDE_DISTANCE);
|
||||
this.labels.more = false;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelJob () {
|
||||
const actionText = strings.get('CANCEL');
|
||||
const hdr = strings.get('warnings.CANCEL_HEADER');
|
||||
const warning = strings.get('warnings.CANCEL_BODY');
|
||||
|
||||
const id = resource.model.get('id');
|
||||
const name = $filter('sanitize')(resource.model.get('name'));
|
||||
|
||||
const body = `<div class="Prompt-bodyQuery">${warning}</div>`;
|
||||
const resourceName = `#${id} ${name}`;
|
||||
|
||||
const method = 'POST';
|
||||
const url = `${resource.model.path}/${id}/cancel/`;
|
||||
|
||||
const errorHandler = createErrorHandler('cancel job', method);
|
||||
|
||||
const action = () => {
|
||||
wait('start');
|
||||
$http({ method, url })
|
||||
.then(() => $state.go('jobs'))
|
||||
.catch(errorHandler)
|
||||
.finally(() => {
|
||||
$(ELEMENT_PROMPT_MODAL).modal('hide');
|
||||
wait('stop');
|
||||
});
|
||||
};
|
||||
|
||||
prompt({ hdr, resourceName, body, actionText, action });
|
||||
}
|
||||
|
||||
function deleteJob () {
|
||||
return;
|
||||
}
|
||||
|
||||
function AtDetailsController (
|
||||
_$http_,
|
||||
_$filter_,
|
||||
_$state_,
|
||||
_error_,
|
||||
_prompt_,
|
||||
_strings_,
|
||||
_wait_,
|
||||
ParseTypeChange,
|
||||
ParseVariableString,
|
||||
) {
|
||||
const vm = this || {};
|
||||
|
||||
$http = _$http_;
|
||||
$filter = _$filter_;
|
||||
$state = _$state_;
|
||||
|
||||
error = _error_;
|
||||
// resource = _resource_;
|
||||
parse = ParseVariableString;
|
||||
prompt = _prompt_;
|
||||
strings = _strings_;
|
||||
wait = _wait_;
|
||||
|
||||
// statusChoices = mapChoices(resource.options('status.choices'));
|
||||
|
||||
vm.init = scope => {
|
||||
vm.job = scope.job || {};
|
||||
resource = scope.resource;
|
||||
|
||||
vm.status = getStatusDetails(scope.status);
|
||||
vm.startTime = getStartTimeDetails();
|
||||
vm.finishTime = getFinishTimeDetails();
|
||||
vm.jobType = getJobTypeDetails();
|
||||
vm.jobTemplate = getJobTemplateDetails();
|
||||
vm.sourceWorkflowJob = getSourceWorkflowJobDetails();
|
||||
vm.inventory = getInventoryDetails();
|
||||
vm.project = getProjectDetails();
|
||||
vm.scmRevision = getSCMRevisionDetails();
|
||||
vm.playbook = getPlaybookDetails();
|
||||
vm.resultTraceback = getResultTracebackDetails();
|
||||
vm.launchedBy = getLaunchedByDetails();
|
||||
vm.jobExplanation = getJobExplanationDetails();
|
||||
vm.verbosity = getVerbosityDetails();
|
||||
vm.machineCredential = getMachineCredentialDetails();
|
||||
vm.forks = getForkDetails();
|
||||
vm.limit = getLimitDetails();
|
||||
vm.instanceGroup = getInstanceGroupDetails();
|
||||
vm.jobTags = getJobTagDetails();
|
||||
vm.skipTags = getSkipTagDetails();
|
||||
vm.extraVars = getExtraVarsDetails();
|
||||
vm.labels = getLabelDetails();
|
||||
|
||||
vm.cancelJob = cancelJob;
|
||||
vm.deleteJob = deleteJob;
|
||||
vm.toggleLabels = toggleLabels;
|
||||
|
||||
// codemirror
|
||||
const cm = { parseType: 'yaml', variables: vm.extraVars.value, $apply: scope.$apply };
|
||||
ParseTypeChange({ scope: cm, field_id: 'cm-extra-vars', readOnly: true });
|
||||
|
||||
scope.$watch('status', value => { vm.status = getStatusDetails(value); });
|
||||
}
|
||||
}
|
||||
|
||||
AtDetailsController.$inject = [
|
||||
'$http',
|
||||
'$filter',
|
||||
'$state',
|
||||
'ProcessErrors',
|
||||
'Prompt',
|
||||
'JobStrings',
|
||||
'Wait',
|
||||
'ParseTypeChange',
|
||||
'ParseVariableString',
|
||||
];
|
||||
|
||||
function atDetailsLink (scope, el, attrs, controllers) {
|
||||
const [atDetailsController] = controllers;
|
||||
|
||||
atDetailsController.init(scope);
|
||||
}
|
||||
|
||||
function atDetails () {
|
||||
return {
|
||||
templateUrl,
|
||||
restrict: 'E',
|
||||
require: ['atDetails'],
|
||||
controllerAs: 'vm',
|
||||
link: atDetailsLink,
|
||||
controller: AtDetailsController,
|
||||
scope: {
|
||||
job: '=',
|
||||
status: '=',
|
||||
resource: '=',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default atDetails;
|
||||
236
awx/ui/client/features/output/details.partial.html
Normal file
236
awx/ui/client/features/output/details.partial.html
Normal file
@ -0,0 +1,236 @@
|
||||
|
||||
<!-- LEFT PANE HEADER -->
|
||||
<div class="JobResults-panelHeader">
|
||||
<div class="JobResults-panelHeaderText" translate> DETAILS</div>
|
||||
<!-- LEFT PANE HEADER ACTIONS -->
|
||||
<div class="JobResults-panelHeaderButtonActions">
|
||||
<!-- RELAUNCH ACTION -->
|
||||
<at-relaunch state="vm.job"></at-relaunch>
|
||||
|
||||
<!-- CANCEL ACTION -->
|
||||
<button class="List-actionButton List-actionButton--delete"
|
||||
data-placement="top"
|
||||
ng-click="vm.cancelJob()"
|
||||
ng-show="vm.status == 'running' || vm.status =='pending' "
|
||||
aw-tool-tip="{{'Cancel' | translate}}"
|
||||
data-original-title="" title="">
|
||||
<i class="fa fa-minus-circle"></i>
|
||||
</button>
|
||||
|
||||
<!-- DELETE ACTION -->
|
||||
<button class="List-actionButton List-actionButton--delete"
|
||||
data-placement="top"
|
||||
ng-click="vm.deleteJob()"
|
||||
ng-hide="vm.status == 'running' || vm.status == 'pending' || !job.summary_fields.user_capabilities.delete"
|
||||
aw-tool-tip="{{'Delete' | translate}}"
|
||||
data-original-title=""
|
||||
title="">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LEFT PANE DETAILS GROUP -->
|
||||
<div>
|
||||
<!-- STATUS DETAIL -->
|
||||
<div class="JobResults-resultRow">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.status.label}}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<i class="JobResults-statusResultIcon fa icon-job-{{ vm.status.value }}"></i>
|
||||
{{ vm.status.displayValue | translate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- START TIME DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.startTime">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.startTime.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
{{ vm.startTime.displayValue }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FINISHED TIME DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-show="vm.startTime">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.finishTime.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
{{ vm.finishTime.displayValue }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RESULTS TRACEBACK DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.resultTraceback">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.resultTraceback.label }}</label>
|
||||
<div class="JobResults-resultRowText" ng-bind-html="vm.resultTraceback.value"></div>
|
||||
</div>
|
||||
|
||||
<!-- TEMPLATE DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-show="vm.jobTemplate">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.jobTemplate.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<a href="{{ vm.jobTemplate.link }}" aw-tool-tip="{{'Edit the job template' | translate}}" data-placement="top">
|
||||
{{ vm.jobTemplate.value }}
|
||||
</a>
|
||||
|
||||
<a href="{{ vm.sourceWorkflowJob.link }}" ng-if="vm.sourceWorkflowJob" aw-tool-tip="{{'View workflow results' | translate}}" data-placement="top" data-original-title="" title="">
|
||||
<i class="WorkflowBadge"> W</i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JOB TYPE DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.jobType">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.jobType.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.jobType.displayValue }}</div>
|
||||
</div>
|
||||
|
||||
<!-- LAUNCHED BY DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.launchedBy">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.launchedBy.label }}</label>
|
||||
<div ng-if="vm.launchedBy.link" class="JobResults-resultRowText">
|
||||
<a href="{{ vm.launchedBy.link }}" aw-tool-tip="{{ vm.launchedBy.tooltip }}" data-placement="top">
|
||||
{{ vm.launchedBy.value }}
|
||||
</a>
|
||||
</div>
|
||||
<div ng-if="!vm.launchedBy.link" class="jobResults-resultRowText">
|
||||
{{ vm.launchedBy.value }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- INVENTORY DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.inventory">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.inventory.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<a href="{{ vm.inventory.link }}" aw-tool-tip="{{ vm.inventory.tooltip }}" data-placement="top">
|
||||
{{ vm.inventory.value }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PROJECT DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.project">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.project.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<a href="{{ vm.project.update.link }}"
|
||||
ng-if="vm.project.update"
|
||||
aw-tool-tip="{{ vm.project.update.tooltip }}"
|
||||
data-placement="top">
|
||||
<i class="JobResults-statusResultIcon fa icon-job-{{ vm.project.update.status }}"></i>
|
||||
</a>
|
||||
<a href="{{ vm.project.link }}"
|
||||
aw-tool-tip="{{ vm.project.tooltip }}"
|
||||
data-placement="top">
|
||||
{{ vm.project.value }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- REVISION DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.scmRevision">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.scmRevision.label }}</label>
|
||||
<at-truncate string="{{ vm.scmRevision.value }}" maxLength="7" class="JobResults-resultRowText"></at-truncate>
|
||||
</div>
|
||||
|
||||
<!-- PLAYBOOK DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.playbook">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.playbook.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.playbook.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- MACHINE CREDENTIAL DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-show="vm.machineCredential">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.machineCredential.label }}</label>
|
||||
<div class="JobResults-resultRowText">
|
||||
<a href="{{ vm.machineCredential.link }}"
|
||||
aw-tool-tip="{{ vm.machineCredential.tooltip }}"
|
||||
data-placement="top">
|
||||
{{ vm.machineCredential.value }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FORKS DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.forks">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.forks.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.forks.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- LIMIT DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.limit">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.limit.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.limit.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- VERBOSITY DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.verbosity">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.verbosity.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.verbosity.displayValue }}</div>
|
||||
</div>
|
||||
|
||||
<!-- IG DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.instanceGroup">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.instanceGroup.label }}</label>
|
||||
<div class="JobResults-resultRowText JobResults-resultRowText--instanceGroup">
|
||||
{{ vm.instanceGroup.value }}
|
||||
<span class="JobResults-isolatedBadge" ng-if="vm.instanceGroup.isolated">
|
||||
{{ vm.instanceGroup.isolated }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAGS DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.jobTags">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.jobTags.label }}</label>
|
||||
<div class="JobResults-resultRowText">{{ vm.jobTags.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- SKIP TAGS DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-if="vm.skipTags">
|
||||
<label class="JobResults-resultRowLabel">{{ vm.skipTags.label }}</label>
|
||||
<div class="JobResults-resultRowText"> {{ vm.skipTags.value }}</div>
|
||||
</div>
|
||||
|
||||
<!-- EXTRA VARIABLES DETAIL -->
|
||||
<div class="JobResults-resultRow JobResults-resultRow--variables" ng-show="vm.extraVars">
|
||||
<label class="JobResults-resultRowLabel JobResults-resultRowLabel--fullWidth">
|
||||
<span>{{ vm.extraVars.label }}</span>
|
||||
<i class="JobResults-extraVarsHelp fa fa-question-circle"
|
||||
aw-tool-tip="{{ vm.extraVars.tooltip }}"
|
||||
data-placement="top">
|
||||
</i>
|
||||
</label>
|
||||
<textarea
|
||||
disabled="disabled"
|
||||
rows="6"
|
||||
ng-model="vm.extraVars.value"
|
||||
name="variables"
|
||||
class="form-control Form-textArea Form-textAreaLabel Form-formGroup--fullWidth"
|
||||
id="cm-extra-vars">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
<!-- LABELS DETAIL -->
|
||||
<div class="JobResults-resultRow" ng-show="vm.labels">
|
||||
<div class="JobResults-resultRow">
|
||||
<a class="JobResults-resultRowLabel JobResults-resultRowLabel--fullWidth"
|
||||
ng-show="vm.labels.more"
|
||||
href=""
|
||||
ng-click="vm.toggleLabels()">
|
||||
<span translate>Labels</span>
|
||||
<i class="JobResults-expandArrow fa fa-caret-right"></i>
|
||||
</a>
|
||||
<a class="JobResults-resultRowLabel JobResults-resultRowLabel--fullWidth"
|
||||
ng-show="!vm.labels.more"
|
||||
href=""
|
||||
ng-click="vm.toggleLabels()">
|
||||
<span translate>Labels</span>
|
||||
<i class="JobResults-expandArrow fa fa-caret-down"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div id="job-results-labels" class="LabelList JobResults-resultRowText JobResults-resultRowText--fullWidth">
|
||||
<div ng-repeat="label in vm.labels.value" class="LabelList-tagContainer">
|
||||
<div class="LabelList-tag"><div class="LabelList-name">{{ label }}</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -67,6 +67,13 @@ function JobsIndexController (
|
||||
vm.removeSearchTag = removeSearchTag;
|
||||
vm.searchTags = getSearchTags(getCurrentQueryset());
|
||||
|
||||
// details
|
||||
vm.details = {
|
||||
job: resource.model.model.GET,
|
||||
status: resource.model.model.GET.status,
|
||||
resource,
|
||||
};
|
||||
|
||||
render.requestAnimationFrame(() => init());
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import RenderService from '~features/output/render.service';
|
||||
import ScrollService from '~features/output/scroll.service';
|
||||
import SearchKeyDirective from '~features/output/search-key.directive';
|
||||
import StreamService from '~features/output/stream.service';
|
||||
import DetailsDirective from '~features/output/details.directive.js';
|
||||
|
||||
const Template = require('~features/output/index.view.html');
|
||||
|
||||
@ -55,21 +56,21 @@ function resolveResource (
|
||||
}
|
||||
|
||||
const params = { page_size: PAGE_SIZE, order_by: 'start_line' };
|
||||
const config = { pageCache: PAGE_CACHE, pageLimit: PAGE_LIMIT, params };
|
||||
|
||||
if (job_event_search) {
|
||||
const searchParams = qs.encodeQuerysetObject(qs.decodeArr(job_event_search));
|
||||
const queryParams = qs.encodeQuerysetObject(qs.decodeArr(job_event_search));
|
||||
|
||||
Object.assign(params, searchParams);
|
||||
Object.assign(config.params, queryParams);
|
||||
}
|
||||
|
||||
Wait('start');
|
||||
return new Resource('get', id)
|
||||
.then(model => model.extend(related, {
|
||||
pageCache: PAGE_CACHE,
|
||||
pageLimit: PAGE_LIMIT,
|
||||
params,
|
||||
}))
|
||||
.then(model => ({
|
||||
return new Resource(['get', 'options'], [id, id])
|
||||
.then(model => Promise.all([
|
||||
model.extend('labels'),
|
||||
model.extend(related, config)
|
||||
]))
|
||||
.then(([ model ]) => ({
|
||||
id,
|
||||
type,
|
||||
model,
|
||||
@ -197,6 +198,7 @@ angular
|
||||
.service('JobPageService', PageService)
|
||||
.service('JobScrollService', ScrollService)
|
||||
.service('JobStreamService', StreamService)
|
||||
.directive('atDetails', DetailsDirective)
|
||||
.directive('atSearchKey', SearchKeyDirective)
|
||||
.run(JobsRun);
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<div class="container-fluid">
|
||||
<div class="col-md-4">
|
||||
<at-panel>
|
||||
<at-details job="vm.details.job" status="vm.details.status" resource="vm.details.resource"></at-details>
|
||||
<p><button class="btn" ng-click="vm.clear(true)">Page Mode</button></p>
|
||||
</at-panel>
|
||||
</div>
|
||||
|
||||
@ -7,6 +7,11 @@ function JobsStrings (BaseString) {
|
||||
ns.state = {
|
||||
TITLE: t.s('JOBZ')
|
||||
};
|
||||
|
||||
ns.warnings = {
|
||||
CANCEL_BODY: t.s('Are you sure you want to cancel this job?'),
|
||||
CANCEL_HEADER: t.s('Cancel Job'),
|
||||
};
|
||||
}
|
||||
|
||||
JobsStrings.$inject = ['BaseStringService'];
|
||||
|
||||
@ -353,10 +353,11 @@ function has (method, keys) {
|
||||
return value !== undefined && value !== null;
|
||||
}
|
||||
|
||||
function extend (related, config) {
|
||||
function extend (related, config = {}) {
|
||||
|
||||
const req = this.parseRequestConfig('GET', config);
|
||||
|
||||
if (config.params.page_size) {
|
||||
if (_.get(config, 'params.page_size')) {
|
||||
this.page.size = config.params.page_size;
|
||||
this.page.current = 1;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user