diff --git a/ui/app/controllers/jobs/job/index.js b/ui/app/controllers/jobs/job/index.js index eae91858f7a6..18a9b685d658 100644 --- a/ui/app/controllers/jobs/job/index.js +++ b/ui/app/controllers/jobs/job/index.js @@ -1,5 +1,6 @@ import { inject as service } from '@ember/service'; import { alias } from '@ember/object/computed'; +import { computed } from '@ember/object'; import Controller from '@ember/controller'; import WithNamespaceResetting from 'nomad-ui/mixins/with-namespace-resetting'; import { action } from '@ember/object'; @@ -8,6 +9,29 @@ import classic from 'ember-classic-decorator'; @classic export default class IndexController extends Controller.extend(WithNamespaceResetting) { @service system; + @service store; + + @computed('job') + get uniqueNodes() { + // add datacenter filter + const allocs = this.job.allocations; + const nodes = allocs.mapBy('node'); + const uniqueNodes = nodes.uniqBy('id').toArray(); + return uniqueNodes.map(nodeId => { + return { + [nodeId.get('id')]: allocs + .toArray() + .filter(alloc => nodeId.get('id') === alloc.get('node.id')) + .map(alloc => alloc.getProperties('clientStatus')) + .map(alloc => alloc.clientStatus), + }; + }); + } + + @computed('node') + get totalNodes() { + return this.store.peekAll('node').toArray().length; + } queryParams = [ { diff --git a/ui/app/routes/jobs/job/index.js b/ui/app/routes/jobs/job/index.js index 4bea45f1f2d7..933fcf95ba95 100644 --- a/ui/app/routes/jobs/job/index.js +++ b/ui/app/routes/jobs/job/index.js @@ -4,6 +4,12 @@ import { watchRecord, watchRelationship, watchAll } from 'nomad-ui/utils/propert import WithWatchers from 'nomad-ui/mixins/with-watchers'; export default class IndexRoute extends Route.extend(WithWatchers) { + async model() { + // Optimizing future node look ups by preemptively loading everything + await this.store.findAll('node'); + return this.modelFor('jobs.job'); + } + startWatchers(controller, model) { if (!model) { return; @@ -16,6 +22,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) { latestDeployment: model.get('supportsDeployments') && this.watchLatestDeployment.perform(model), list: model.get('hasChildren') && this.watchAll.perform(), + nodes: /*model.type === 'sysbatch' && */ this.watchNodes.perform(), }); } @@ -33,6 +40,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) { @watchRecord('job') watch; @watchAll('job') watchAll; + @watchAll('node') watchNodes; @watchRecord('job-summary') watchSummary; @watchRelationship('allocations') watchAllocations; @watchRelationship('evaluations') watchEvaluations; @@ -41,6 +49,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) { @collect( 'watch', 'watchAll', + 'watchNodes', 'watchSummary', 'watchAllocations', 'watchEvaluations', diff --git a/ui/app/styles/charts/colors.scss b/ui/app/styles/charts/colors.scss index 50f370607f67..252922061776 100644 --- a/ui/app/styles/charts/colors.scss +++ b/ui/app/styles/charts/colors.scss @@ -4,6 +4,8 @@ $running: $primary; $complete: $nomad-green-dark; $failed: $danger; $lost: $dark; +$not-scheduled: $grey-darker; +$degraded: $warning; .chart { .queued { @@ -37,6 +39,14 @@ $lost: $dark; .lost { fill: $lost; } + + .not-scheduled { + fill: $not-scheduled; + } + + .degraded { + fill: $degraded; + } } .color-swatch { @@ -102,6 +112,14 @@ $lost: $dark; background: $lost; } + &.not-scheduled { + fill: $not-scheduled; + } + + &.degraded { + fill: $degraded; + } + @each $name, $pair in $colors { $color: nth($pair, 1); diff --git a/ui/app/templates/components/job-page/parts/summary.hbs b/ui/app/templates/components/job-page/parts/summary.hbs index e90cdff53753..11130804d604 100644 --- a/ui/app/templates/components/job-page/parts/summary.hbs +++ b/ui/app/templates/components/job-page/parts/summary.hbs @@ -1,4 +1,62 @@ + +
+
+ {{#if a.item.hasChildren}} + Children Status + + {{a.item.summary.totalChildren}} + + {{else}} + Client Status + + {{a.item.summary.totalAllocs}} + + {{/if}} +
+ + {{#unless a.isOpen}} +
+
+ {{#if a.item.hasChildren}} + {{#if (gt a.item.totalChildren 0)}} + + {{else}} + No Children + {{/if}} + {{else}} + + {{/if}} +
+
+ {{/unless}} +
+
+ + {{#component (if a.item.hasChildren "children-status-bar" "client-status-bar") + allocationContainer=a.item.summary + job=a.item.summary + nodes=this.nodes + totalNodes=this.totalNodes + class="split-view" as |chart|}} +
    + {{#each chart.data as |datum index|}} +
  1. + + {{datum.value}} + + {{datum.label}} + +
  2. + {{/each}} +
+ {{/component}} +
+
+ +
+ +
diff --git a/ui/app/templates/components/job-page/service.hbs b/ui/app/templates/components/job-page/service.hbs index d8180f244a8c..915e88bab962 100644 --- a/ui/app/templates/components/job-page/service.hbs +++ b/ui/app/templates/components/job-page/service.hbs @@ -19,7 +19,7 @@ {{/each}} {{/if}} - + diff --git a/ui/app/templates/components/job-page/system.hbs b/ui/app/templates/components/job-page/system.hbs index 5e0abbea25f7..a7c8520b2ae6 100644 --- a/ui/app/templates/components/job-page/system.hbs +++ b/ui/app/templates/components/job-page/system.hbs @@ -19,7 +19,7 @@ {{/each}} {{/if}} - + diff --git a/ui/app/templates/jobs/job/index.hbs b/ui/app/templates/jobs/job/index.hbs index 56d18ec2e57c..82d97770fbe1 100644 --- a/ui/app/templates/jobs/job/index.hbs +++ b/ui/app/templates/jobs/job/index.hbs @@ -1,6 +1,8 @@ {{page-title "Job " this.model.name}} {{component (concat "job-page/" this.model.templateType) job=this.model + nodes=this.uniqueNodes + totalNodes=this.totalNodes sortProperty=this.sortProperty sortDescending=this.sortDescending currentPage=this.currentPage