diff --git a/ui/app/controllers/optimize.js b/ui/app/controllers/optimize.js index 9d16d4e37..1fd4d9960 100644 --- a/ui/app/controllers/optimize.js +++ b/ui/app/controllers/optimize.js @@ -8,13 +8,18 @@ import { task } from 'ember-concurrency'; import intersection from 'lodash.intersection'; import { serialize, deserializedQueryParam as selection } from 'nomad-ui/utils/qp-serialize'; +import EmberObject, { computed } from '@ember/object'; +import { alias } from '@ember/object/computed'; +import Searchable from 'nomad-ui/mixins/searchable'; +import classic from 'ember-classic-decorator'; + export default class OptimizeController extends Controller { @controller('optimize/summary') summaryController; queryParams = [ - // { - // searchTerm: 'search', - // }, + { + searchTerm: 'search', + }, { qpType: 'type', }, @@ -29,6 +34,16 @@ export default class OptimizeController extends Controller { }, ]; + constructor() { + super(...arguments); + + this.summarySearch = RecommendationSummarySearch.create({ + dataSource: this, + }); + } + + @tracked searchTerm = ''; + @tracked qpType = ''; @tracked qpStatus = ''; @tracked qpDatacenter = ''; @@ -112,7 +127,7 @@ export default class OptimizeController extends Controller { // A summary’s job must match ALL filter facets, but it can match ANY selection within a facet // Always return early to prevent unnecessary facet predicates. - return this.model.filter(summary => { + return this.summarySearch.listSearched.filter(summary => { const job = summary.get('job'); if (types.length && !types.includes(job.get('displayType'))) { @@ -166,3 +181,18 @@ export default class OptimizeController extends Controller { this[queryParam] = serialize(selection); } } + +@classic +class RecommendationSummarySearch extends EmberObject.extend(Searchable) { + @computed + get fuzzySearchProps() { + return ['slug']; + } + + @alias('dataSource.model') listToSearch; + @alias('dataSource.searchTerm') searchTerm; + + exactMatchEnabled = false; + fuzzySearchEnabled = true; + includeFuzzySearchMatches = true; +} diff --git a/ui/app/models/recommendation-summary.js b/ui/app/models/recommendation-summary.js index 20a718d7e..818f7a023 100644 --- a/ui/app/models/recommendation-summary.js +++ b/ui/app/models/recommendation-summary.js @@ -47,6 +47,6 @@ export default class RecommendationSummary extends Model { } get slug() { - return `${this.jobId}/${this.taskGroupName}`; + return `${get(this, 'job.name')}/${this.taskGroupName}`; } } diff --git a/ui/app/templates/optimize.hbs b/ui/app/templates/optimize.hbs index 8cac4f433..b191e2538 100644 --- a/ui/app/templates/optimize.hbs +++ b/ui/app/templates/optimize.hbs @@ -4,11 +4,10 @@
{{#if @model}} - {{!-- --}} + @placeholder="Search recommendations..." /> {{/if}}
diff --git a/ui/tests/acceptance/optimize-test.js b/ui/tests/acceptance/optimize-test.js index 0716d117c..5396e0f29 100644 --- a/ui/tests/acceptance/optimize-test.js +++ b/ui/tests/acceptance/optimize-test.js @@ -351,7 +351,7 @@ module('Acceptance | optimize', function(hooks) { }); }); -module('Acceptance | optimize facets', function(hooks) { +module('Acceptance | optimize search and facets', function(hooks) { setupApplicationTest(hooks); setupMirage(hooks); @@ -366,6 +366,29 @@ module('Acceptance | optimize facets', function(hooks) { window.localStorage.nomadTokenSecret = managementToken.secretId; }); + test('search field narrows summary table results', async function(assert) { + server.createList('job', 1, { + name: 'oooooo', + createRecommendations: true, + groupsCount: 2, + groupTaskCount: 4, + }); + + server.createList('job', 1, { + name: 'pppppp', + createRecommendations: true, + groupsCount: 2, + groupTaskCount: 4, + }); + + await Optimize.visit(); + + await Optimize.search.fillIn('ooo'); + + assert.equal(Optimize.recommendationSummaries.length, 2); + assert.ok(Optimize.recommendationSummaries[0].slug.startsWith('oooooo')); + }); + test('the optimize page has appropriate faceted search options', async function(assert) { server.createList('job', 4, { status: 'running', diff --git a/ui/tests/pages/optimize.js b/ui/tests/pages/optimize.js index 9ec25bc97..bafe0e849 100644 --- a/ui/tests/pages/optimize.js +++ b/ui/tests/pages/optimize.js @@ -24,6 +24,10 @@ export default create({ return this.breadcrumbs.toArray().find(crumb => crumb.id === id); }, + search: { + scope: '[data-test-recommendation-summaries-search] input', + }, + card: recommendationCard, recommendationSummaries: collection('[data-test-recommendation-summary-row]', {