Skip to content

Commit

Permalink
[ui, deployments] Show a "Latest Deployment Status" cell within the J…
Browse files Browse the repository at this point in the history
…ob Status panel on steady service jobs (#17246)

* Failed or lost cell condensed

* Latest Deployment cell

* Stylistic changes and deploying state fixup

* Rewritten tooltip message and updated lost/failed tests

* failed-or-lost cell updates to job status panel acceptance tests
  • Loading branch information
philrenaud authored May 25, 2023
1 parent 9ff1d92 commit 3bde355
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 104 deletions.
74 changes: 41 additions & 33 deletions ui/app/components/job-status/failed-or-lost.hbs
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
<section class="failed-or-lost">
<h4>
{{@title}}
<span
class="tooltip multiline text-center"
role="tooltip"
aria-label={{@description}}
>
<FlightIcon @name="info" />
<h4>Replaced Allocations</h4>
<div class="failed-or-lost-links">
{{#if @supportsRescheduling}}
<span>
<span
class="tooltip multiline text-center"
role="tooltip"
aria-label="Allocations that have been rescheduled, on another node if possible, due to failure or manual restart"
>
<FlightIcon @name="info" />
</span>
<ConditionalLinkTo
@condition={{@rescheduledAllocs.length}}
@route="jobs.job.allocations"
@model={{@job}}
@query={{hash scheduling='["has-been-rescheduled"]' version=(concat '[' @job.latestDeployment.versionNumber ']')}}
@label="View Allocations"
>
{{@rescheduledAllocs.length}} Rescheduled
</ConditionalLinkTo>
</span>
{{/if}}

<span>
<span
class="tooltip multiline text-center"
role="tooltip"
aria-label="Allocations that have been restarted in-place due to a task failure or manual restart"
>
<FlightIcon @name="info" />
</span>
<ConditionalLinkTo
@condition={{@restartedAllocs.length}}
@route="jobs.job.allocations"
@model={{@job}}
@query={{hash scheduling='["has-been-restarted"]' version=(concat '[' @job.latestDeployment.versionNumber ']')}}
@label="View Allocations"
>
{{@restartedAllocs.length}} Restarted
</ConditionalLinkTo>
</span>
</h4>
{{#if (eq @title "Rescheduled")}}
<ConditionalLinkTo
@condition={{this.shouldLinkToAllocations}}
@route="jobs.job.allocations"
@model={{@job}}
@query={{hash scheduling='["has-been-rescheduled"]' version=(concat '[' @job.latestDeployment.versionNumber ']')}}
@label="View Allocations"
@class="failed-or-lost-link"
>
{{@allocs.length}}
</ConditionalLinkTo>
{{/if}}
{{#if (eq @title "Restarted")}}
<ConditionalLinkTo
@condition={{this.shouldLinkToAllocations}}
@route="jobs.job.allocations"
@model={{@job}}
@query={{hash scheduling='["has-been-restarted"]' version=(concat '[' @job.latestDeployment.versionNumber ']')}}
@label="View Allocations"
@class="failed-or-lost-link"
>
{{@allocs.length}}
</ConditionalLinkTo>
{{/if}}
</div>
</section>
7 changes: 0 additions & 7 deletions ui/app/components/job-status/failed-or-lost.js

This file was deleted.

10 changes: 10 additions & 0 deletions ui/app/components/job-status/latest-deployment.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<section class="latest-deployment">
<LinkTo @route="jobs.job.deployments" @model={{@job}}>
<h4>
Latest Deployment
<FlightIcon @name="arrow-right" />
</h4>
</LinkTo>
<Hds::Badge @text={{capitalize this.status}} @size="small" @color={{this.statusColor}} @type="filled" />
<p>{{this.healthyAllocs}}/{{this.desiredTotal}} Healthy</p>
</section>
31 changes: 31 additions & 0 deletions ui/app/components/job-status/latest-deployment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Component from '@glimmer/component';
import { alias } from '@ember/object/computed';

export default class JobStatusLatestDeploymentComponent extends Component {
@alias('args.job.latestDeployment') deployment;
@alias('deployment.status') status;

get healthyAllocs() {
return this.deployment
.get('taskGroupSummaries')
.mapBy('healthyAllocs')
.reduce((sum, count) => sum + count, 0);
}
get desiredTotal() {
return this.deployment
.get('taskGroupSummaries')
.mapBy('desiredTotal')
.reduce((sum, count) => sum + count, 0);
}

get statusColor() {
switch (this.status) {
case 'successful':
return 'success';
case 'failed':
return 'critical';
default:
return 'neutral';
}
}
}
13 changes: 3 additions & 10 deletions ui/app/components/job-status/panel/deploying.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,10 @@
</legend>

<JobStatus::FailedOrLost
@allocs={{this.rescheduledAllocs}}
@rescheduledAllocs={{this.rescheduledAllocs}}
@restartedAllocs={{this.restartedAllocs}}
@job={{@job}}
@title="Rescheduled"
@description="Allocations that have been rescheduled, on another node if possible, due to failure during deployment"
/>

<JobStatus::FailedOrLost
@allocs={{this.restartedAllocs}}
@job={{@job}}
@title="Restarted"
@description="Allocations that have been restarted in-place due to a task failure during deployment"
@supportsRescheduling={{true}}
/>

</div>
Expand Down
20 changes: 8 additions & 12 deletions ui/app/components/job-status/panel/steady.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</h3>
<JobStatus::AllocationStatusRow @allocBlocks={{this.allocBlocks}} @steady={{true}} />

<div class="legend-and-summary">
<div class="legend-and-summary {{if @job.latestDeployment "has-latest-deployment"}}">
<legend>
{{#each this.allocTypes as |type|}}
<ConditionalLinkTo
Expand All @@ -58,20 +58,12 @@
{{/each}}
</legend>

{{#if this.supportsRescheduling}}
<JobStatus::FailedOrLost
@allocs={{this.rescheduledAllocs}}
@job={{@job}}
@title="Rescheduled"
@description="Allocations that have been rescheduled, on another node if possible, due to failure"
/>
{{/if}}

<JobStatus::FailedOrLost
@allocs={{this.restartedAllocs}}
@rescheduledAllocs={{this.rescheduledAllocs}}
@restartedAllocs={{this.restartedAllocs}}
@job={{@job}}
@title="Restarted"
@description="Allocations that have been restarted in-place due to a task failure"
@supportsRescheduling={{this.supportsRescheduling}}
/>

<section class="versions">
Expand All @@ -92,6 +84,10 @@
</ul>
</section>

{{#if @job.latestDeployment}}
<JobStatus::LatestDeployment @job={{@job}} />
{{/if}}

</div>

<div class="history-and-params">
Expand Down
28 changes: 18 additions & 10 deletions ui/app/styles/components/job-status-panel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@
// grid-area: legend-and-summary;
// TODO: may revisit this grid-area later, but is currently used in 2 competing ways
display: grid;
gap: 0.5rem;
grid-template-columns: 55% 15% 15% 15%;
gap: 1rem;
grid-template-columns: 3fr 1fr 1fr;
&.has-latest-deployment {
grid-template-columns: 3fr 1fr 1fr 1fr;
}

& > section > h4,
& > legend > h4 {
& > legend > h4,
& > section > a > h4 {
margin-bottom: 0.5rem;
}

Expand All @@ -62,8 +66,6 @@
gap: 0.5rem;
}
.versions {
display: grid;
gap: 0.5rem;
& > ul {
display: grid;
grid-template-columns: repeat(auto-fit, 100px);
Expand All @@ -76,12 +78,18 @@
}
}
}
.latest-deployment {
h4 svg {
position: relative;
top: 3px;
}
}

.failed-or-lost {
.failed-or-lost-link {
display: block;
font-size: 1.5rem;
font-weight: bold;
.failed-or-lost > div {
display: grid;
gap: 3px;
.tooltip {
top: 3px;
}
}
}
Expand Down
45 changes: 24 additions & 21 deletions ui/tests/acceptance/job-status-panel-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -648,29 +648,29 @@ module('Acceptance | job status panel', function (hooks) {
await visit(`/jobs/${job.id}`);
assert.dom('.job-status-panel').exists();
assert
.dom('.failed-or-lost')
.dom('.failed-or-lost-links > span')
.exists({ count: 2 }, 'Restarted and Rescheduled cells are both present');

let rescheduledCell = [...findAll('.failed-or-lost')][0];
let restartedCell = [...findAll('.failed-or-lost')][1];
// await this.pauseTest();
let rescheduledCell = [...findAll('.failed-or-lost-links > span')][0];
let restartedCell = [...findAll('.failed-or-lost-links > span')][1];

// Check that the title in each cell has the right text
assert.dom(rescheduledCell.querySelector('h4')).hasText('Rescheduled');
assert.dom(restartedCell.querySelector('h4')).hasText('Restarted');
assert.dom(rescheduledCell).hasText('0 Rescheduled');
assert.dom(restartedCell).hasText('0 Restarted');

// Check that both values are zero and non-links
assert
.dom(rescheduledCell.querySelector('a'))
.doesNotExist('Rescheduled cell is not a link');
assert
.dom(rescheduledCell.querySelector('.failed-or-lost-link'))
.hasText('0', 'Rescheduled cell has zero value');
.dom(rescheduledCell)
.hasText('0 Rescheduled', 'Rescheduled cell has zero value');
assert
.dom(restartedCell.querySelector('a'))
.doesNotExist('Restarted cell is not a link');
assert
.dom(restartedCell.querySelector('.failed-or-lost-link'))
.hasText('0', 'Restarted cell has zero value');
.dom(restartedCell)
.hasText('0 Restarted', 'Restarted cell has zero value');

// A wild event appears! Change a recent task event to type "Restarting" in a task state:
this.store
Expand All @@ -687,9 +687,9 @@ module('Acceptance | job status panel', function (hooks) {
await settled();

assert
.dom(restartedCell.querySelector('.failed-or-lost-link'))
.dom(restartedCell)
.hasText(
'1',
'1 Restarted',
'Restarted cell updates when a task event with type "Restarting" is added'
);

Expand All @@ -708,9 +708,9 @@ module('Acceptance | job status panel', function (hooks) {

// Trigger a reschedule! Set up a desiredTransition object with a Reschedule property on one of the allocations.
assert
.dom(restartedCell.querySelector('.failed-or-lost-link'))
.dom(restartedCell)
.hasText(
'2',
'2 Restarted',
'Restarted cell updates when a second task event with type "Restarting" is added'
);

Expand All @@ -725,8 +725,11 @@ module('Acceptance | job status panel', function (hooks) {
await settled();

assert
.dom(rescheduledCell.querySelector('.failed-or-lost-link'))
.hasText('1', 'Rescheduled cell updates when desiredTransition is set');
.dom(rescheduledCell)
.hasText(
'1 Rescheduled',
'Rescheduled cell updates when desiredTransition is set'
);
assert
.dom(rescheduledCell.querySelector('a'))
.exists('Rescheduled cell with a non-zero number is now a link');
Expand Down Expand Up @@ -900,10 +903,10 @@ module('Acceptance | job status panel', function (hooks) {
await visit(`/jobs/${job.id}`);
assert.dom('.job-status-panel').exists();
assert.dom('.failed-or-lost').exists({ count: 1 });
assert.dom('.failed-or-lost h4').hasText('Restarted');
assert.dom('.failed-or-lost h4').hasText('Replaced Allocations');
assert
.dom('.failed-or-lost-link')
.hasText('0', 'Restarted cell at zero by default');
.dom('.failed-or-lost-links > span')
.hasText('0 Restarted', 'Restarted cell at zero by default');

// A wild event appears! Change a recent task event to type "Restarting" in a task state:
this.store
Expand All @@ -920,9 +923,9 @@ module('Acceptance | job status panel', function (hooks) {
await settled();

assert
.dom('.failed-or-lost-link')
.dom('.failed-or-lost-links > span')
.hasText(
'1',
'1 Restarted',
'Restarted cell updates when a task event with type "Restarting" is added'
);
});
Expand Down
Loading

0 comments on commit 3bde355

Please sign in to comment.