[ui] Update the Task Lifecycle Status chart (#24133)

* Updates the Task Lifecycle Status chart to show which pre/poststart task may have failed

* Default colour to prevent HDS error

* De-duplicated data-test attr and added is-active and is-finished test classes

* Failed and Pending state tests
This commit is contained in:
Phil Renaud
2024-11-07 13:57:58 -05:00
committed by GitHub
parent a0ff07393b
commit 3d9003879e
7 changed files with 96 additions and 58 deletions

3
.changelog/24133.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:improvement
ui: Indicates prestart/poststart tasks by running/failed/pending status
```

View File

@@ -11,6 +11,48 @@ import classic from 'ember-classic-decorator';
@classic
@tagName('')
export default class LifecycleChartRow extends Component {
@computed('taskState.{failed,state}')
get taskColor() {
let color = 'neutral';
if (this.taskState?.state === 'running') {
color = 'success';
}
if (this.taskState?.state === 'pending') {
color = 'neutral';
}
if (this.taskState?.state === 'dead') {
if (this.taskState?.failed) {
color = 'critical';
} else {
color = 'neutral';
}
}
return color;
}
get taskIcon() {
let icon;
if (this.taskState?.state === 'running') {
icon = 'running';
}
if (this.taskState?.state === 'pending') {
icon = 'test';
}
if (this.taskState?.state === 'dead') {
if (this.taskState?.failed) {
icon = 'alert-circle';
} else {
if (this.taskState?.startedAt) {
icon = 'check-circle';
} else {
icon = 'minus-circle';
}
}
}
return icon;
}
@computed('taskState.state')
get activeClass() {
if (this.taskState && this.taskState.state === 'running') {

View File

@@ -84,50 +84,33 @@
.lifecycle-chart-row {
position: relative;
padding: 0.25rem 0.5rem;
.task {
margin: 0.55em 0.9em;
padding: 0.3em 0.55em;
border: 1px solid $grey-blue;
border-radius: $radius;
background: white;
$pending-mid: rgba(255, 255, 255, 0.5);
.hds-alert {
padding: 4px 8px;
.name {
font-weight: $weight-semibold;
&.pending {
position: relative;
overflow: hidden;
border-style: dashed;
a {
color: inherit;
text-decoration: none;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
-60deg,
transparent,
$pending-mid,
transparent
);
animation: shimmer 2s ease-in-out infinite;
}
}
&:hover {
.name a {
text-decoration: underline;
}
}
.lifecycle {
font-size: $size-7;
color: $ui-gray-400;
}
}
&.is-active {
.task {
border-color: $nomad-green;
background: lighten($nomad-green, 50%);
.lifecycle {
color: $ui-gray-500;
}
}
}
&.is-finished {
.task {
color: $ui-gray-400;
}
}
&.main {
@@ -159,9 +142,5 @@
&.poststop {
margin-left: 75%;
}
&:last-child .task {
margin-bottom: 0.9em;
}
}
}

View File

@@ -3,11 +3,13 @@
SPDX-License-Identifier: BUSL-1.1
~}}
<div
class="lifecycle-chart-row {{this.task.lifecycleName}} {{this.activeClass}} {{this.finishedClass}}"
data-test-lifecycle-task>
<div class="task">
<div class="name" data-test-name>
<div class="lifecycle-chart-row {{this.task.lifecycleName}} {{this.activeClass}} {{this.finishedClass}}" data-test-lifecycle-task>
<Hds::Alert
@type="inline"
@color={{this.taskColor}}
class="{{if (eq this.taskState.state "pending") "pending"}}"
@icon={{this.taskIcon}} as |A|>
<A.Title class="name" data-test-name>
{{#if this.taskState}}
<LinkTo @route="allocations.allocation.task" @models={{array this.taskState.allocation this.taskState}}>
{{this.task.name}}
@@ -15,7 +17,9 @@
{{else}}
{{this.task.name}}
{{/if}}
</div>
</A.Title>
<A.Description>
<div class="lifecycle" data-test-lifecycle>{{capitalize this.lifecycleLabel}} Task</div>
</div>
</A.Description>
</Hds::Alert>
</div>

View File

@@ -117,7 +117,7 @@ module('Integration | Component | lifecycle-chart', function (hooks) {
});
test('it reflects phase and task states when states are passed in', async function (assert) {
assert.expect(24);
assert.expect(26);
this.set(
'taskStates',
@@ -152,8 +152,12 @@ module('Integration | Component | lifecycle-chart', function (hooks) {
this.set('taskStates.4.finishedAt', new Date());
this.set('taskStates.4.state', 'dead');
this.set('taskStates.4.failed', true);
this.set('taskStates.0.state', 'pending');
await settled();
assert.ok(Chart.tasks[3].child.pending, 'Task is pending');
assert.ok(Chart.tasks[5].child.failed, 'Task is failed');
assert.ok(Chart.tasks[5].isFinished);
});

View File

@@ -23,6 +23,12 @@ export default {
isActive: hasClass('is-active'),
isFinished: hasClass('is-finished'),
child: {
scope: '.hds-alert',
failed: hasClass('hds-alert--color-critical'),
pending: hasClass('pending'),
},
isMain: hasClass('main'),
isPrestartEphemeral: hasClass('prestart-ephemeral'),
isPrestartSidecar: hasClass('prestart-sidecar'),