mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 04:31:21 -03:30
implement new style jobs list in ui
This commit is contained in:
parent
e7cfe1e0b6
commit
95f80ce512
@ -6,6 +6,7 @@ import atFeaturesApplications from '~features/applications';
|
||||
import atFeaturesCredentials from '~features/credentials';
|
||||
import atFeaturesTemplates from '~features/templates';
|
||||
import atFeaturesUsers from '~features/users';
|
||||
import atFeaturesJobs from '~features/jobs';
|
||||
|
||||
const MODULE_NAME = 'at.features';
|
||||
|
||||
@ -16,7 +17,8 @@ angular.module(MODULE_NAME, [
|
||||
atFeaturesApplications,
|
||||
atFeaturesCredentials,
|
||||
atFeaturesTemplates,
|
||||
atFeaturesUsers
|
||||
atFeaturesUsers,
|
||||
atFeaturesJobs
|
||||
]);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
13
awx/ui/client/features/jobs/index.js
Normal file
13
awx/ui/client/features/jobs/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import JobsStrings from './jobs.strings';
|
||||
import jobsRoute from './jobs.route';
|
||||
|
||||
const MODULE_NAME = 'at.features.jobs';
|
||||
|
||||
angular
|
||||
.module(MODULE_NAME, [])
|
||||
.service('JobsStrings', JobsStrings)
|
||||
.run(['$stateExtender', ($stateExtender) => {
|
||||
$stateExtender.addState(jobsRoute);
|
||||
}]);
|
||||
|
||||
export default MODULE_NAME;
|
||||
19
awx/ui/client/features/jobs/index.view.html
Normal file
19
awx/ui/client/features/jobs/index.view.html
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="tab-pane" id="jobs-page">
|
||||
<at-panel ng-cloak id="htmlTemplate">
|
||||
<div>
|
||||
<div ng-hide="$state.is('jobs.schedules')">
|
||||
<at-panel-heading hide-dismiss="true">
|
||||
<translate>JOBS</translate>
|
||||
</at-panel-heading>
|
||||
<div ui-view="jobsList"></div>
|
||||
</div>
|
||||
<div ng-hide="!$state.is('jobs.schedules')">
|
||||
<at-panel-heading hide-dismiss="true">
|
||||
<translate>SCHEDULES</translate>
|
||||
</at-panel-heading>
|
||||
<div ui-view="schedulesList"></div>
|
||||
</div>
|
||||
</div>
|
||||
</at-panel>
|
||||
<div ng-include="'/static/partials/logviewer.html'"></div>
|
||||
</div>
|
||||
67
awx/ui/client/features/jobs/jobs.route.js
Normal file
67
awx/ui/client/features/jobs/jobs.route.js
Normal file
@ -0,0 +1,67 @@
|
||||
import { N_ } from '../../src/i18n';
|
||||
import jobsListController from './jobsList.controller';
|
||||
|
||||
const indexTemplate = require('~features/jobs/index.view.html');
|
||||
const jobsListTemplate = require('~features/jobs/jobsList.view.html');
|
||||
|
||||
export default {
|
||||
searchPrefix: 'job',
|
||||
name: 'jobs',
|
||||
url: '/jobs',
|
||||
ncyBreadcrumb: {
|
||||
label: N_('JOBS')
|
||||
},
|
||||
params: {
|
||||
job_search: {
|
||||
value: {
|
||||
not__launch_type: 'sync',
|
||||
order_by: '-finished'
|
||||
},
|
||||
dynamic: true,
|
||||
squash: false
|
||||
}
|
||||
},
|
||||
data: {
|
||||
socket: {
|
||||
groups: {
|
||||
jobs: ['status_changed'],
|
||||
schedules: ['changed']
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
resolvedModels: [
|
||||
'UnifiedJobModel',
|
||||
(UnifiedJob) => {
|
||||
const models = [
|
||||
new UnifiedJob(['options']),
|
||||
];
|
||||
return Promise.all(models);
|
||||
},
|
||||
],
|
||||
Dataset: [
|
||||
'$stateParams',
|
||||
'Wait',
|
||||
'GetBasePath',
|
||||
'QuerySet',
|
||||
($stateParams, Wait, GetBasePath, qs) => {
|
||||
const searchParam = $stateParams.job_search;
|
||||
const searchPath = GetBasePath('unified_jobs');
|
||||
|
||||
Wait('start');
|
||||
return qs.search(searchPath, searchParam)
|
||||
.finally(() => Wait('stop'));
|
||||
}
|
||||
],
|
||||
},
|
||||
views: {
|
||||
'@': {
|
||||
templateUrl: indexTemplate
|
||||
},
|
||||
'jobsList@jobs': {
|
||||
templateUrl: jobsListTemplate,
|
||||
controller: jobsListController,
|
||||
controllerAs: 'vm'
|
||||
}
|
||||
}
|
||||
};
|
||||
20
awx/ui/client/features/jobs/jobs.strings.js
Normal file
20
awx/ui/client/features/jobs/jobs.strings.js
Normal file
@ -0,0 +1,20 @@
|
||||
function JobsStrings (BaseString) {
|
||||
BaseString.call(this, 'jobs');
|
||||
|
||||
const { t } = this;
|
||||
const ns = this.jobs;
|
||||
|
||||
ns.list = {
|
||||
ROW_ITEM_LABEL_STARTED: t.s('Started'),
|
||||
ROW_ITEM_LABEL_FINISHED: t.s('Finished'),
|
||||
ROW_ITEM_LABEL_LAUNCHED_BY: t.s('Launched By'),
|
||||
ROW_ITEM_LABEL_JOB_TEMPLATE: t.s('Job Template'),
|
||||
ROW_ITEM_LABEL_INVENTORY: t.s('Inventory'),
|
||||
ROW_ITEM_LABEL_PROJECT: t.s('Project'),
|
||||
ROW_ITEM_LABEL_CREDENTIALS: t.s('Credentials'),
|
||||
};
|
||||
}
|
||||
|
||||
JobsStrings.$inject = ['BaseStringService'];
|
||||
|
||||
export default JobsStrings;
|
||||
137
awx/ui/client/features/jobs/jobsList.controller.js
Normal file
137
awx/ui/client/features/jobs/jobsList.controller.js
Normal file
@ -0,0 +1,137 @@
|
||||
/** ***********************************************
|
||||
* Copyright (c) 2018 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
************************************************ */
|
||||
const mapChoices = choices => Object
|
||||
.assign(...choices.map(([k, v]) => ({ [k]: v })));
|
||||
|
||||
function ListJobsController (
|
||||
$scope,
|
||||
$state,
|
||||
Dataset,
|
||||
resolvedModels,
|
||||
strings,
|
||||
qs,
|
||||
Prompt,
|
||||
$filter,
|
||||
ProcessErrors,
|
||||
Wait,
|
||||
Rest
|
||||
) {
|
||||
const vm = this || {};
|
||||
const [unifiedJob] = resolvedModels;
|
||||
|
||||
vm.strings = strings;
|
||||
|
||||
// smart-search
|
||||
const name = 'jobs';
|
||||
const iterator = 'job';
|
||||
const key = 'job_dataset';
|
||||
|
||||
$scope.list = { iterator, name };
|
||||
$scope.collection = { iterator, basePath: 'unified_jobs' };
|
||||
$scope[key] = Dataset.data;
|
||||
$scope[name] = Dataset.data.results;
|
||||
$scope.$on('updateDataset', (e, dataset) => {
|
||||
$scope[key] = dataset;
|
||||
$scope[name] = dataset.results;
|
||||
});
|
||||
$scope.$on('ws-jobs', () => {
|
||||
qs.search(unifiedJob.path, $state.params.job_search)
|
||||
.then(({ data }) => {
|
||||
$scope.$emit('updateDataset', data);
|
||||
});
|
||||
});
|
||||
|
||||
vm.jobTypes = mapChoices(unifiedJob
|
||||
.options('actions.GET.type.choices'));
|
||||
|
||||
vm.getLink = ({ type, id }) => {
|
||||
let link;
|
||||
|
||||
switch (type) {
|
||||
case 'job':
|
||||
link = `/#/jobs/${id}`;
|
||||
break;
|
||||
case 'ad_hoc_command':
|
||||
link = `/#/ad_hoc_commands/${id}`;
|
||||
break;
|
||||
case 'system_job':
|
||||
link = `/#/management_jobs/${id}`;
|
||||
break;
|
||||
case 'project_update':
|
||||
link = `/#/scm_update/${id}`;
|
||||
break;
|
||||
case 'inventory_update':
|
||||
link = `/#/inventory_sync/${id}`;
|
||||
break;
|
||||
case 'workflow_job':
|
||||
link = `/#/workflows/${id}`;
|
||||
break;
|
||||
default:
|
||||
link = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return link;
|
||||
};
|
||||
|
||||
vm.deleteJob = (job) => {
|
||||
const action = () => {
|
||||
$('#prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
Rest.setUrl(job.url);
|
||||
Rest.destroy()
|
||||
.then(() => {
|
||||
let reloadListStateParams = null;
|
||||
|
||||
if ($scope.jobs.length === 1 && $state.params.job_search &&
|
||||
!_.isEmpty($state.params.job_search.page) &&
|
||||
$state.params.job_search.page !== '1') {
|
||||
const page = `${(parseInt(reloadListStateParams
|
||||
.job_search.page, 10) - 1)}`;
|
||||
reloadListStateParams = _.cloneDeep($state.params);
|
||||
reloadListStateParams.job_search.page = page;
|
||||
}
|
||||
|
||||
$state.go('.', reloadListStateParams, { reload: true });
|
||||
})
|
||||
.catch(({ data, status }) => {
|
||||
ProcessErrors($scope, data, status, null, {
|
||||
hdr: strings.get('error.HEADER'),
|
||||
msg: strings.get('error.CALL', { path: `${job.url}`, status })
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
Wait('stop');
|
||||
});
|
||||
};
|
||||
|
||||
const deleteModalBody = `<div class="Prompt-bodyQuery">${strings.get('deleteResource.CONFIRM', 'job')}</div>`;
|
||||
|
||||
Prompt({
|
||||
hdr: strings.get('deleteResource.HEADER'),
|
||||
resourceName: $filter('sanitize')(job.name),
|
||||
body: deleteModalBody,
|
||||
action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
ListJobsController.$inject = [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Dataset',
|
||||
'resolvedModels',
|
||||
'JobsStrings',
|
||||
'QuerySet',
|
||||
'Prompt',
|
||||
'$filter',
|
||||
'ProcessErrors',
|
||||
'Wait',
|
||||
'Rest'
|
||||
];
|
||||
|
||||
export default ListJobsController;
|
||||
82
awx/ui/client/features/jobs/jobsList.view.html
Normal file
82
awx/ui/client/features/jobs/jobsList.view.html
Normal file
@ -0,0 +1,82 @@
|
||||
<at-panel-body>
|
||||
<div class="at-List-toolbar">
|
||||
<smart-search
|
||||
class="at-List-search"
|
||||
django-model="jobs"
|
||||
base-path="unified_jobs"
|
||||
iterator="job"
|
||||
list="list"
|
||||
dataset="job_dataset"
|
||||
collection="collection"
|
||||
search-tags="searchTags"
|
||||
query-set="querySet">
|
||||
</smart-search>
|
||||
</div>
|
||||
<at-list results="jobs">
|
||||
<!-- TODO: implement resources are missing red indicator as present in mockup -->
|
||||
<at-row ng-repeat="job in jobs" job-id="{{ job.id }}">
|
||||
<div class="at-Row-items">
|
||||
<!-- TODO: include workflow tab as well -->
|
||||
<at-row-item
|
||||
status="{{ job.status }}"
|
||||
status-tip="Job {{job.status}}. Click for details."
|
||||
header-value="{{ job.name }}"
|
||||
header-link="{{ vm.getLink(job) }}"
|
||||
header-tag="{{ vm.jobTypes[job.type] }}">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_STARTED') }}"
|
||||
value="{{ job.started | longDate }}"
|
||||
inline="true">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_FINISHED') }}"
|
||||
value="{{ job.finished | longDate }}"
|
||||
inline="true">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_LAUNCHED_BY') }}"
|
||||
value="{{ job.summary_fields.created_by.username }}"
|
||||
value-link="/#/users/{{ job.summary_fields.created_by.id }}">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_JOB_TEMPLATE') }}"
|
||||
value="{{ job.summary_fields.job_template.name }}"
|
||||
value-link="/#/templates/job_template/{{ job.summary_fields.job_template.id }}">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_INVENTORY') }}"
|
||||
value="{{ job.summary_fields.inventory.name }}"
|
||||
value-link="/#/inventories/{{ job.summary_fields.inventory.id }}">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_PROJECT') }}"
|
||||
value="{{ job.summary_fields.project.name }}"
|
||||
value-link="/#/projects/{{ job.summary_fields.project.id }}">
|
||||
</at-row-item>
|
||||
<at-row-item
|
||||
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_CREDENTIALS') }}"
|
||||
tag-values="job.summary_fields.credentials"
|
||||
tags-are-creds="true">
|
||||
</at-row-item>
|
||||
<labels-list class="LabelList" show-delete="false" is-row-item="true">
|
||||
</labels-list>
|
||||
</div>
|
||||
<div class="at-Row-actions">
|
||||
<at-relaunch
|
||||
ng-show="job.summary_fields.user_capabilities.start">
|
||||
</at-relaunch>
|
||||
<at-row-action icon="fa-trash" ng-click="vm.deleteJob(job)"
|
||||
ng-show="job.summary_fields.user_capabilities.delete">
|
||||
</at-row-action>
|
||||
</div>
|
||||
</at-row>
|
||||
</at-list>
|
||||
<paginate
|
||||
collection="collection"
|
||||
dataset="job_dataset"
|
||||
iterator="job"
|
||||
base-path="unified_jobs"
|
||||
query-set="querySet">
|
||||
</paginate>
|
||||
</at-panel-body>
|
||||
@ -151,6 +151,10 @@
|
||||
line-height: @at-height-list-row-item;
|
||||
}
|
||||
|
||||
.at-RowItem-status {
|
||||
margin-right: @at-margin-right-list-row-item-status;
|
||||
}
|
||||
|
||||
.at-RowItem--isHeader {
|
||||
color: @at-color-body-text;
|
||||
margin-bottom: @at-margin-bottom-list-header;
|
||||
@ -263,6 +267,16 @@
|
||||
margin: 2px 20px 0 0;
|
||||
}
|
||||
|
||||
.at-RowItem--inline {
|
||||
display: inline-flex;
|
||||
margin-right: @at-margin-right-list-row-item-inline;
|
||||
|
||||
.at-RowItem-label {
|
||||
width: auto;
|
||||
margin-right: @at-margin-right-list-row-item-inline-label;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @at-breakpoint-compact-list) {
|
||||
.at-Row-actions {
|
||||
flex-direction: column;
|
||||
@ -271,4 +285,14 @@
|
||||
.at-RowAction {
|
||||
margin: @at-margin-list-row-action-mobile;
|
||||
}
|
||||
|
||||
.at-RowItem--inline {
|
||||
display: flex;
|
||||
margin-right: inherit;
|
||||
|
||||
.at-RowItem-label {
|
||||
width: @at-width-list-row-item-label;
|
||||
margin-right: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,10 +7,13 @@ function atRowItem () {
|
||||
transclude: true,
|
||||
templateUrl,
|
||||
scope: {
|
||||
inline: '@',
|
||||
badge: '@',
|
||||
headerValue: '@',
|
||||
headerLink: '@',
|
||||
headerTag: '@',
|
||||
status: '@',
|
||||
statusTip: '@',
|
||||
labelValue: '@',
|
||||
labelLink: '@',
|
||||
labelState: '@',
|
||||
|
||||
@ -1,5 +1,13 @@
|
||||
<div class="at-RowItem" ng-class="{'at-RowItem--isHeader': headerValue}"
|
||||
ng-show="headerValue || value || (smartStatus && smartStatus.summary_fields.recent_jobs.length) || (tagValues && tagValues.length)">
|
||||
<div class="at-RowItem" ng-class="{'at-RowItem--isHeader': headerValue, 'at-RowItem--inline': inline}"
|
||||
ng-show="status || headerValue || value || (smartStatus && smartStatus.summary_fields.recent_jobs.length) || (tagValues && tagValues.length)">
|
||||
<div class="at-RowItem-status" ng-if="status">
|
||||
<a ng-if="headerLink" ng-href="{{ headerLink }}"
|
||||
aw-tool-tip="{{ statusTip }}" aw-tip-watch="statusTip"
|
||||
data-placement="top">
|
||||
<i class="fa icon-job-{{ status }}"></i>
|
||||
</a>
|
||||
<i ng-if="!headerLink" class="fa icon-job-{{ status }}"></i>
|
||||
</div>
|
||||
<div class="at-RowItem-header" ng-if="headerValue && headerLink">
|
||||
<a ng-href="{{ headerLink }}">{{ headerValue }}</a>
|
||||
</div>
|
||||
@ -41,4 +49,4 @@
|
||||
{{ tag.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
21
awx/ui/client/lib/models/UnifiedJob.js
Normal file
21
awx/ui/client/lib/models/UnifiedJob.js
Normal file
@ -0,0 +1,21 @@
|
||||
let Base;
|
||||
|
||||
function UnifiedJobModel (method, resource, config) {
|
||||
Base.call(this, 'unified_jobs');
|
||||
|
||||
this.Constructor = UnifiedJobModel;
|
||||
|
||||
return this.create(method, resource, config);
|
||||
}
|
||||
|
||||
function UnifiedJobModelLoader (BaseModel) {
|
||||
Base = BaseModel;
|
||||
|
||||
return UnifiedJobModel;
|
||||
}
|
||||
|
||||
UnifiedJobModelLoader.$inject = [
|
||||
'BaseModel'
|
||||
];
|
||||
|
||||
export default UnifiedJobModelLoader;
|
||||
@ -23,6 +23,7 @@ import UnifiedJobTemplate from '~models/UnifiedJobTemplate';
|
||||
import WorkflowJob from '~models/WorkflowJob';
|
||||
import WorkflowJobTemplate from '~models/WorkflowJobTemplate';
|
||||
import WorkflowJobTemplateNode from '~models/WorkflowJobTemplateNode';
|
||||
import UnifiedJob from '~models/UnifiedJob';
|
||||
|
||||
const MODULE_NAME = 'at.lib.models';
|
||||
|
||||
@ -49,6 +50,7 @@ angular
|
||||
.service('OrganizationModel', Organization)
|
||||
.service('ProjectModel', Project)
|
||||
.service('ScheduleModel', Schedule)
|
||||
.service('UnifiedJobModel', UnifiedJob)
|
||||
.service('UnifiedJobTemplateModel', UnifiedJobTemplate)
|
||||
.service('WorkflowJobModel', WorkflowJob)
|
||||
.service('WorkflowJobTemplateModel', WorkflowJobTemplate)
|
||||
|
||||
@ -262,6 +262,9 @@
|
||||
@at-margin-right-list-row-item-tag-icon: 8px;
|
||||
@at-margin-left-list-row-item-tag-container: -10px;
|
||||
@at-margin-list-row-action-mobile: 10px;
|
||||
@at-margin-right-list-row-item-status: @at-space-2x;
|
||||
@at-margin-right-list-row-item-inline: @at-space-4x;
|
||||
@at-margin-right-list-row-item-inline-label: @at-space-2x;
|
||||
|
||||
@at-height-divider: @at-margin-panel;
|
||||
@at-height-input: 30px;
|
||||
|
||||
@ -86,4 +86,4 @@ InstanceJobsController.$inject = [
|
||||
'InstanceModel'
|
||||
];
|
||||
|
||||
export default InstanceJobsController;
|
||||
export default InstanceJobsController;
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import { N_ } from '../i18n';
|
||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||
|
||||
export default {
|
||||
searchPrefix: 'job',
|
||||
name: 'jobs',
|
||||
url: '/jobs',
|
||||
ncyBreadcrumb: {
|
||||
label: N_("JOBS")
|
||||
},
|
||||
params: {
|
||||
job_search: {
|
||||
value: {
|
||||
not__launch_type: 'sync',
|
||||
order_by: '-finished'
|
||||
},
|
||||
dynamic: true,
|
||||
squash: false
|
||||
}
|
||||
},
|
||||
data: {
|
||||
socket: {
|
||||
"groups": {
|
||||
"jobs": ["status_changed"],
|
||||
"schedules": ["changed"]
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
Dataset: ['AllJobsList', 'QuerySet', '$stateParams', 'GetBasePath', (list, qs, $stateParams, GetBasePath) => {
|
||||
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||
}],
|
||||
ListDefinition: ['AllJobsList', (list) => {
|
||||
return list;
|
||||
}]
|
||||
},
|
||||
views: {
|
||||
'@': {
|
||||
templateUrl: templateUrl('jobs/jobs')
|
||||
},
|
||||
'list@jobs': {
|
||||
templateProvider: function(AllJobsList, generateList) {
|
||||
let html = generateList.build({
|
||||
list: AllJobsList,
|
||||
mode: 'edit'
|
||||
});
|
||||
return html;
|
||||
},
|
||||
controller: 'JobsList'
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -5,15 +5,11 @@
|
||||
*************************************************/
|
||||
|
||||
import jobsList from './jobs-list.controller';
|
||||
import jobsRoute from './jobs.route';
|
||||
import DeleteJob from './factories/delete-job.factory';
|
||||
import AllJobsList from './all-jobs.list';
|
||||
|
||||
export default
|
||||
angular.module('JobsModule', [])
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
$stateExtender.addState(jobsRoute);
|
||||
}])
|
||||
.controller('JobsList', jobsList)
|
||||
.factory('DeleteJob', DeleteJob)
|
||||
.factory('AllJobsList', AllJobsList);
|
||||
|
||||
@ -349,7 +349,7 @@ export default
|
||||
}]
|
||||
},
|
||||
views: {
|
||||
'list@jobs': {
|
||||
'schedulesList@jobs': {
|
||||
templateProvider: function(ScheduleList, generateList){
|
||||
let html = generateList.build({
|
||||
list: ScheduleList,
|
||||
|
||||
@ -95,6 +95,11 @@ export default
|
||||
if (scope.$parent.$parent.template) {
|
||||
scope.labels = scope.$parent.$parent.template.summary_fields.labels.results.slice(0, 5);
|
||||
scope.count = scope.$parent.$parent.template.summary_fields.labels.count;
|
||||
} else if (scope.$parent.$parent.job) {
|
||||
if (_.has(scope, '$parent.$parent.job.summary_fields.labels.results')) {
|
||||
scope.labels = scope.$parent.$parent.job.summary_fields.labels.results.slice(0, 5);
|
||||
scope.count = scope.$parent.$parent.job.summary_fields.labels.count;
|
||||
}
|
||||
} else {
|
||||
scope.$watchCollection(scope.$parent.list.iterator, function() {
|
||||
// To keep the array of labels fresh, we need to set up a watcher - otherwise, the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user