Skip to content

Commit

Permalink
[ui] Color indicators for server/client status (#18318)
Browse files Browse the repository at this point in the history
* Color the status cell for servers and nodes

* Testfix and changelog

* Leader indicator moved post-word

* Icon and badge treatment

* Capitalizing test checks

* HDS badges dont expose statusClass like we used to, so stop checking for it
  • Loading branch information
philrenaud authored Sep 20, 2023
1 parent d7bd47d commit cf8dde0
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 33 deletions.
3 changes: 3 additions & 0 deletions .changelog/18318.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: color-code node and server status cells
```
4 changes: 2 additions & 2 deletions .github/workflows/ember-test-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
with:
ref: ${{ github.event.pull_request.base.sha }}
- uses: nanasess/setup-chromedriver@6fb8f5ffa6b7dc11e631ff695fbd2fec0b04bb52 # v2.1.1
- uses: nanasess/setup-chromedriver@69cc01d772a1595b8aee87d52f53e71b3904d9d0 # v2.1.2
- name: Use Node.js
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0
with:
Expand All @@ -35,7 +35,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- uses: nanasess/setup-chromedriver@6fb8f5ffa6b7dc11e631ff695fbd2fec0b04bb52 # v2.1.1
- uses: nanasess/setup-chromedriver@69cc01d772a1595b8aee87d52f53e71b3904d9d0 # v2.1.2
- name: Use Node.js
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0
with:
Expand Down
30 changes: 26 additions & 4 deletions ui/app/components/client-node-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,37 @@ export default class ClientNodeRow extends Component.extend(
@watchRelationship('allocations') watch;

@computed('node.compositeStatus')
get compositeStatusClass() {
get nodeStatusColor() {
let compositeStatus = this.get('node.compositeStatus');

if (compositeStatus === 'draining') {
return 'status-text is-info';
return 'neutral';
} else if (compositeStatus === 'ineligible') {
return 'status-text is-warning';
return 'warning';
} else if (compositeStatus === 'down') {
return 'status-text is-danger';
return 'critical';
} else if (compositeStatus === 'ready') {
return 'success';
} else if (compositeStatus === 'initializing') {
return 'neutral';
} else {
return 'neutral';
}
}
@computed('node.compositeStatus')
get nodeStatusIcon() {
let compositeStatus = this.get('node.compositeStatus');

if (compositeStatus === 'draining') {
return 'minus-circle';
} else if (compositeStatus === 'ineligible') {
return 'skip';
} else if (compositeStatus === 'down') {
return 'x-circle';
} else if (compositeStatus === 'ready') {
return 'check-circle';
} else if (compositeStatus === 'initializing') {
return 'entry-point';
} else {
return '';
}
Expand Down
16 changes: 16 additions & 0 deletions ui/app/components/server-agent-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,20 @@ export default class ServerAgentRow extends Component {
click() {
this.goToAgent();
}

@computed('agent.status')
get agentStatusColor() {
let agentStatus = this.get('agent.status');
if (agentStatus === 'alive') {
return 'success';
} else if (agentStatus === 'failed') {
return 'critical';
} else if (agentStatus === 'leaving') {
return 'neutral';
} else if (agentStatus === 'left') {
return 'neutral';
} else {
return '';
}
}
}
7 changes: 6 additions & 1 deletion ui/app/templates/components/client-node-row.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
<td data-test-client-name class="is-200px is-truncatable" title="{{this.node.name}}">{{this.node.name}}</td>
<td data-test-client-composite-status>
<span class="tooltip" aria-label="{{this.node.status}} / {{if this.node.isDraining "draining" "not draining"}} / {{if this.node.isEligible "eligible" "not eligible"}}">
<span class="{{this.compositeStatusClass}}">{{this.node.compositeStatus}}</span>
<Hds::Badge
@text={{capitalize this.node.compositeStatus}}
@icon={{this.nodeStatusIcon}}
@color={{this.nodeStatusColor}}
@size="large"
/>
</span>
</td>
<td data-test-client-address class="is-200px is-truncatable">{{this.node.httpAddr}}</td>
Expand Down
18 changes: 16 additions & 2 deletions ui/app/templates/components/server-agent-row.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,22 @@
action=(action this.goToAgent)
}}
><LinkTo @route="servers.server" @model={{this.agent.id}} class="is-primary">{{this.agent.name}}</LinkTo></td>
<td data-test-server-status>{{this.agent.status}}</td>
<td data-test-server-is-leader>{{if this.agent.isLeader "True" "False"}}</td>
<td data-test-server-status><span>
<Hds::Badge
@text={{capitalize this.agent.status}}
@color={{this.agentStatusColor}}
@size="large"
/>
</span></td>
<td data-test-server-is-leader>

<Hds::Badge
@text={{if this.agent.isLeader "True" "False"}}
@icon={{if this.agent.isLeader "check-circle" ""}}
@color={{if this.agent.isLeader "success" "neutral"}}
@size="large"
/>
</td>
<td data-test-server-address class="is-200px is-truncatable">{{this.agent.address}}</td>
<td data-test-server-port>{{this.agent.serfPort}}</td>
<td data-test-server-datacenter>{{this.agent.datacenter}}</td>
Expand Down
32 changes: 11 additions & 21 deletions ui/tests/acceptance/clients-list-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ module('Acceptance | clients list', function (hooks) {
assert.equal(nodeRow.nodePool, node.nodePool, 'Node Pool');
assert.equal(
nodeRow.compositeStatus.text,
'draining',
'Draining',
'Combined status, draining, and eligbility'
);
assert.equal(nodeRow.address, node.httpAddr);
Expand Down Expand Up @@ -111,7 +111,7 @@ module('Acceptance | clients list', function (hooks) {
assert.equal(nodeRow.id, node.id.split('-')[0], 'ID');
assert.equal(
nodeRow.compositeStatus.text,
'ready',
'Ready',
'Combined status, draining, and eligbility'
);
assert.equal(nodeRow.allocations, running.length, '# Allocations');
Expand Down Expand Up @@ -156,38 +156,28 @@ module('Acceptance | clients list', function (hooks) {
});

await ClientsList.visit();

ClientsList.nodes[0].compositeStatus.as((readyClient) => {
assert.equal(readyClient.text, 'ready');
assert.ok(readyClient.isUnformatted, 'expected no status class');
assert.equal(readyClient.text, 'Ready');
console.log('readyClient', readyClient.text);
assert.equal(readyClient.tooltip, 'ready / not draining / eligible');
});

assert.equal(ClientsList.nodes[1].compositeStatus.text, 'initializing');
assert.equal(ClientsList.nodes[2].compositeStatus.text, 'down');
assert.equal(ClientsList.nodes[1].compositeStatus.text, 'Initializing');
assert.equal(ClientsList.nodes[2].compositeStatus.text, 'Down');
assert.equal(
ClientsList.nodes[2].compositeStatus.text,
'down',
'Down',
'down takes priority over ineligible'
);
assert.equal(ClientsList.nodes[4].compositeStatus.text, 'Ineligible');

assert.equal(ClientsList.nodes[4].compositeStatus.text, 'ineligible');
assert.ok(
ClientsList.nodes[4].compositeStatus.isWarning,
'expected warning class'
);

assert.equal(ClientsList.nodes[5].compositeStatus.text, 'draining');
assert.ok(
ClientsList.nodes[5].compositeStatus.isInfo,
'expected info class'
);
assert.equal(ClientsList.nodes[5].compositeStatus.text, 'Draining');

await ClientsList.sortBy('compositeStatus');

assert.deepEqual(
ClientsList.nodes.map((n) => n.compositeStatus.text),
['ready', 'initializing', 'ineligible', 'draining', 'down', 'down']
['Ready', 'Initializing', 'Ineligible', 'Draining', 'Down', 'Down']
);

// Simulate a client state change arriving through polling
Expand All @@ -201,7 +191,7 @@ module('Acceptance | clients list', function (hooks) {

assert.deepEqual(
ClientsList.nodes.map((n) => n.compositeStatus.text),
['initializing', 'ineligible', 'ineligible', 'draining', 'down', 'down']
['Initializing', 'Ineligible', 'Ineligible', 'Draining', 'Down', 'Down']
);
});

Expand Down
6 changes: 5 additions & 1 deletion ui/tests/acceptance/servers-list-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ module('Acceptance | servers list', function (hooks) {
const agentRow = ServersList.servers.objectAt(0);

assert.equal(agentRow.name, agent.name, 'Name');
assert.equal(agentRow.status, agent.member.Status, 'Status');
assert.equal(
agentRow.status,
agent.member.Status[0].toUpperCase() + agent.member.Status.substring(1),
'Status'
);
assert.equal(agentRow.leader, 'True', 'Leader?');
assert.equal(agentRow.address, agent.member.Address, 'Address');
assert.equal(agentRow.serfPort, agent.member.Port, 'Serf Port');
Expand Down
5 changes: 3 additions & 2 deletions ui/tests/pages/clients/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ export default create({

tooltip: attribute('aria-label', '.tooltip'),

isInfo: hasClass('is-info', '.status-text'),
isWarning: hasClass('is-warning', '.status-text'),
isInfo: hasClass('is-info'),
isSuccess: hasClass('is-success'),
isWarning: hasClass('is-warning'),
isUnformatted: isHidden('.status-text'),
},

Expand Down

0 comments on commit cf8dde0

Please sign in to comment.