mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
[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:
3
.changelog/24133.txt
Normal file
3
.changelog/24133.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:improvement
|
||||||
|
ui: Indicates prestart/poststart tasks by running/failed/pending status
|
||||||
|
```
|
||||||
@@ -11,6 +11,48 @@ import classic from 'ember-classic-decorator';
|
|||||||
@classic
|
@classic
|
||||||
@tagName('')
|
@tagName('')
|
||||||
export default class LifecycleChartRow extends Component {
|
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')
|
@computed('taskState.state')
|
||||||
get activeClass() {
|
get activeClass() {
|
||||||
if (this.taskState && this.taskState.state === 'running') {
|
if (this.taskState && this.taskState.state === 'running') {
|
||||||
|
|||||||
@@ -84,50 +84,33 @@
|
|||||||
|
|
||||||
.lifecycle-chart-row {
|
.lifecycle-chart-row {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
|
||||||
.task {
|
$pending-mid: rgba(255, 255, 255, 0.5);
|
||||||
margin: 0.55em 0.9em;
|
.hds-alert {
|
||||||
padding: 0.3em 0.55em;
|
padding: 4px 8px;
|
||||||
border: 1px solid $grey-blue;
|
|
||||||
border-radius: $radius;
|
|
||||||
background: white;
|
|
||||||
|
|
||||||
.name {
|
&.pending {
|
||||||
font-weight: $weight-semibold;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-style: dashed;
|
||||||
|
|
||||||
a {
|
&:before {
|
||||||
color: inherit;
|
content: '';
|
||||||
text-decoration: none;
|
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 {
|
&.main {
|
||||||
@@ -159,9 +142,5 @@
|
|||||||
&.poststop {
|
&.poststop {
|
||||||
margin-left: 75%;
|
margin-left: 75%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child .task {
|
|
||||||
margin-bottom: 0.9em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,23 @@
|
|||||||
SPDX-License-Identifier: BUSL-1.1
|
SPDX-License-Identifier: BUSL-1.1
|
||||||
~}}
|
~}}
|
||||||
|
|
||||||
<div
|
<div class="lifecycle-chart-row {{this.task.lifecycleName}} {{this.activeClass}} {{this.finishedClass}}" data-test-lifecycle-task>
|
||||||
class="lifecycle-chart-row {{this.task.lifecycleName}} {{this.activeClass}} {{this.finishedClass}}"
|
<Hds::Alert
|
||||||
data-test-lifecycle-task>
|
@type="inline"
|
||||||
<div class="task">
|
@color={{this.taskColor}}
|
||||||
<div class="name" data-test-name>
|
class="{{if (eq this.taskState.state "pending") "pending"}}"
|
||||||
{{#if this.taskState}}
|
@icon={{this.taskIcon}} as |A|>
|
||||||
<LinkTo @route="allocations.allocation.task" @models={{array this.taskState.allocation this.taskState}}>
|
<A.Title class="name" data-test-name>
|
||||||
{{this.task.name}}
|
{{#if this.taskState}}
|
||||||
</LinkTo>
|
<LinkTo @route="allocations.allocation.task" @models={{array this.taskState.allocation this.taskState}}>
|
||||||
{{else}}
|
|
||||||
{{this.task.name}}
|
{{this.task.name}}
|
||||||
{{/if}}
|
</LinkTo>
|
||||||
</div>
|
{{else}}
|
||||||
|
{{this.task.name}}
|
||||||
|
{{/if}}
|
||||||
|
</A.Title>
|
||||||
|
<A.Description>
|
||||||
<div class="lifecycle" data-test-lifecycle>{{capitalize this.lifecycleLabel}} Task</div>
|
<div class="lifecycle" data-test-lifecycle>{{capitalize this.lifecycleLabel}} Task</div>
|
||||||
</div>
|
</A.Description>
|
||||||
|
</Hds::Alert>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -360,4 +360,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -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) {
|
test('it reflects phase and task states when states are passed in', async function (assert) {
|
||||||
assert.expect(24);
|
assert.expect(26);
|
||||||
|
|
||||||
this.set(
|
this.set(
|
||||||
'taskStates',
|
'taskStates',
|
||||||
@@ -152,8 +152,12 @@ module('Integration | Component | lifecycle-chart', function (hooks) {
|
|||||||
|
|
||||||
this.set('taskStates.4.finishedAt', new Date());
|
this.set('taskStates.4.finishedAt', new Date());
|
||||||
this.set('taskStates.4.state', 'dead');
|
this.set('taskStates.4.state', 'dead');
|
||||||
|
this.set('taskStates.4.failed', true);
|
||||||
|
this.set('taskStates.0.state', 'pending');
|
||||||
await settled();
|
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);
|
assert.ok(Chart.tasks[5].isFinished);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ export default {
|
|||||||
isActive: hasClass('is-active'),
|
isActive: hasClass('is-active'),
|
||||||
isFinished: hasClass('is-finished'),
|
isFinished: hasClass('is-finished'),
|
||||||
|
|
||||||
|
child: {
|
||||||
|
scope: '.hds-alert',
|
||||||
|
failed: hasClass('hds-alert--color-critical'),
|
||||||
|
pending: hasClass('pending'),
|
||||||
|
},
|
||||||
|
|
||||||
isMain: hasClass('main'),
|
isMain: hasClass('main'),
|
||||||
isPrestartEphemeral: hasClass('prestart-ephemeral'),
|
isPrestartEphemeral: hasClass('prestart-ephemeral'),
|
||||||
isPrestartSidecar: hasClass('prestart-sidecar'),
|
isPrestartSidecar: hasClass('prestart-sidecar'),
|
||||||
|
|||||||
Reference in New Issue
Block a user