- {{this.filteredNodes.length}}
- {{if (eq this.filteredNodes.length 1) "client was" "clients were"}}
+ {{this.pre09Nodes.length}}
+ {{if (eq this.pre09Nodes.length 1) "client was" "clients were"}}
filtered from the topology visualization. This is most likely due to the
- {{pluralize "client" this.filteredNodes.length}}
+ {{pluralize "client" this.pre09Nodes.length}}
running a version of Nomad
@@ -24,7 +24,7 @@
+
+
+ {{#if this.model.nodes.length}}
+
+ {{/if}}
+
+
+
+
+
+
+
+
+
+
From a1f347e2a7e54b96f3e013d9cbc9d5ea41ec4f7e Mon Sep 17 00:00:00 2001
From: Phil Renaud
Date: Mon, 17 Oct 2022 14:30:56 -0400
Subject: [PATCH 2/5] Lintfix and changelog
---
.changelog/14913.txt | 3 +++
ui/app/controllers/topology.js | 7 ++++---
2 files changed, 7 insertions(+), 3 deletions(-)
create mode 100644 .changelog/14913.txt
diff --git a/.changelog/14913.txt b/.changelog/14913.txt
new file mode 100644
index 00000000000..511b00a8c75
--- /dev/null
+++ b/.changelog/14913.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+ui: adds searching and filtering to the topology page
+```
diff --git a/ui/app/controllers/topology.js b/ui/app/controllers/topology.js
index 8dfe22be1cc..f12e9450a20 100644
--- a/ui/app/controllers/topology.js
+++ b/ui/app/controllers/topology.js
@@ -1,3 +1,4 @@
+/* eslint-disable ember/no-incorrect-calls-with-inline-anonymous-functions */
import Controller from '@ember/controller';
import { computed, action } from '@ember/object';
import { alias } from '@ember/object/computed';
@@ -63,7 +64,7 @@ export default class TopologyControllers extends Controller.extend(Searchable) {
];
}
- @computed('nodes.[]', 'selectionClass')
+ @computed('model.nodes', 'nodes.[]', 'selectionClass')
get optionsClass() {
const classes = Array.from(new Set(this.model.nodes.mapBy('nodeClass')))
.compact()
@@ -81,7 +82,7 @@ export default class TopologyControllers extends Controller.extend(Searchable) {
return classes.sort().map((dc) => ({ key: dc, label: dc }));
}
- @computed('nodes.[]', 'selectionDatacenter')
+ @computed('model.nodes', 'nodes.[]', 'selectionDatacenter')
get optionsDatacenter() {
const datacenters = Array.from(
new Set(this.model.nodes.mapBy('datacenter'))
@@ -99,7 +100,7 @@ export default class TopologyControllers extends Controller.extend(Searchable) {
return datacenters.sort().map((dc) => ({ key: dc, label: dc }));
}
- @computed('nodes.[]', 'selectionVersion')
+ @computed('model.nodes', 'nodes.[]', 'selectionVersion')
get optionsVersion() {
const versions = Array.from(
new Set(this.model.nodes.mapBy('version'))
From 56bd954fa3bfecf4c8a42e51d006f6b9630cf995 Mon Sep 17 00:00:00 2001
From: Phil Renaud
Date: Mon, 17 Oct 2022 16:14:57 -0400
Subject: [PATCH 3/5] Acceptance tests for topology search and filter
---
ui/app/templates/topology.hbs | 2 +-
ui/tests/acceptance/topology-test.js | 26 +++++++++++++++++++++++++-
ui/tests/pages/topology.js | 8 ++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/ui/app/templates/topology.hbs b/ui/app/templates/topology.hbs
index 5cad3df1eb5..6d3ab76f27a 100644
--- a/ui/app/templates/topology.hbs
+++ b/ui/app/templates/topology.hbs
@@ -466,8 +466,8 @@
{{#if this.model.nodes.length}}
{{/if}}
diff --git a/ui/tests/acceptance/topology-test.js b/ui/tests/acceptance/topology-test.js
index 2d664beccad..87fbca0100d 100644
--- a/ui/tests/acceptance/topology-test.js
+++ b/ui/tests/acceptance/topology-test.js
@@ -1,6 +1,6 @@
/* eslint-disable qunit/require-expect */
import { get } from '@ember/object';
-import { currentURL } from '@ember/test-helpers';
+import { currentURL, typeIn, click } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
@@ -311,4 +311,28 @@ module('Acceptance | topology', function (hooks) {
assert.ok(Topology.filteredNodesWarning.isPresent);
assert.ok(Topology.filteredNodesWarning.message.startsWith('1'));
});
+
+ test('Filtering and Querying reduces the number of nodes shown', async function (assert) {
+ server.createList('node', 10);
+ server.createList('node', 2, {
+ nodeClass: 'foo-bar-baz',
+ });
+ server.createList('allocation', 5);
+
+ await Topology.visit();
+ assert.dom('[data-test-topo-viz-node]').exists({ count: 12 });
+
+ await typeIn('input.node-search', server.schema.nodes.first().name);
+ assert.dom('[data-test-topo-viz-node]').exists({ count: 1 });
+ await typeIn('input.node-search', server.schema.nodes.first().name);
+ assert.dom('[data-test-topo-viz-node]').doesNotExist();
+ await click('[title="Clear search"]');
+ assert.dom('[data-test-topo-viz-node]').exists({ count: 12 });
+
+ await Topology.facets.class.toggle();
+ await Topology.facets.class.options
+ .findOneBy('label', 'foo-bar-baz')
+ .toggle();
+ assert.dom('[data-test-topo-viz-node]').exists({ count: 2 });
+ });
});
diff --git a/ui/tests/pages/topology.js b/ui/tests/pages/topology.js
index c62dfeef050..6442a4d2575 100644
--- a/ui/tests/pages/topology.js
+++ b/ui/tests/pages/topology.js
@@ -8,6 +8,7 @@ import {
visitable,
} from 'ember-cli-page-object';
+import { multiFacet } from 'nomad-ui/tests/pages/components/facet';
import TopoViz from 'nomad-ui/tests/pages/components/topo-viz';
import notification from 'nomad-ui/tests/pages/components/notification';
@@ -19,6 +20,13 @@ export default create({
viz: TopoViz('[data-test-topo-viz]'),
+ facets: {
+ datacenter: multiFacet('[data-test-datacenter-facet]'),
+ class: multiFacet('[data-test-class-facet]'),
+ state: multiFacet('[data-test-state-facet]'),
+ version: multiFacet('[data-test-version-facet]'),
+ },
+
clusterInfoPanel: {
scope: '[data-test-info-panel]',
nodeCount: text('[data-test-node-count]'),
From 6ab4613b8ec53fc667bbcfcf75dbcfcb3ee8893a Mon Sep 17 00:00:00 2001
From: Phil Renaud
Date: Tue, 18 Oct 2022 10:38:52 -0400
Subject: [PATCH 4/5] Search terms also apply to class and dc on topo page
---
ui/app/controllers/topology.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ui/app/controllers/topology.js b/ui/app/controllers/topology.js
index f12e9450a20..f078d5e3b7d 100644
--- a/ui/app/controllers/topology.js
+++ b/ui/app/controllers/topology.js
@@ -143,7 +143,9 @@ export default class TopologyControllers extends Controller.extend(Searchable) {
(selectionClass.length
? selectionClass.includes(node.nodeClass)
: true) &&
- node.name.includes(searchTerm)
+ (node.name.includes(searchTerm) ||
+ node.datacenter.includes(searchTerm) ||
+ node.nodeClass.includes(searchTerm))
);
});
}
From a6331cf8694bbb9291ed534bda3825ce60fe4e60 Mon Sep 17 00:00:00 2001
From: Phil Renaud
Date: Wed, 19 Oct 2022 13:09:30 -0400
Subject: [PATCH 5/5] Initialize queryparam values so as to not break history
state
---
ui/app/controllers/topology.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ui/app/controllers/topology.js b/ui/app/controllers/topology.js
index f078d5e3b7d..901dcaa398c 100644
--- a/ui/app/controllers/topology.js
+++ b/ui/app/controllers/topology.js
@@ -42,6 +42,10 @@ export default class TopologyControllers extends Controller.extend(Searchable) {
];
@tracked searchTerm = '';
+ qpState = '';
+ qpVersion = '';
+ qpClass = '';
+ qpDatacenter = '';
setFacetQueryParam(queryParam, selection) {
this.set(queryParam, serialize(selection));