diff --git a/ui/app/components/global-search/control.js b/ui/app/components/global-search/control.js index c041c6754..6dc65b4bc 100644 --- a/ui/app/components/global-search/control.js +++ b/ui/app/components/global-search/control.js @@ -1,16 +1,16 @@ import Component from '@ember/component'; -import { tagName } from '@ember-decorators/component'; +import { classNames } from '@ember-decorators/component'; import { task } from 'ember-concurrency'; import EmberObject, { action, computed, set } from '@ember/object'; import { alias } from '@ember/object/computed'; import { inject as service } from '@ember/service'; -import { run } from '@ember/runloop'; +import { debounce, run } from '@ember/runloop'; import Searchable from 'nomad-ui/mixins/searchable'; import classic from 'ember-classic-decorator'; const SLASH_KEY = 191; -@tagName('') +@classNames('global-search-container') export default class GlobalSearchControl extends Component { @service dataCaches; @service router; @@ -117,8 +117,15 @@ export default class GlobalSearchControl extends Component { const triggerIsNotActive = !targetClassList.contains('ember-power-select-trigger--active'); if (targetIsTrigger && triggerIsNotActive) { + debounce(this, this.open, 150); + } + } + + @action + onCloseEvent(select, event) { + if (event.key === 'Escape') { run.next(() => { - select.actions.open(); + this.select.actions.setIsActive(false); }); } } @@ -151,6 +158,7 @@ class JobSearch extends EmberObject.extend(Searchable) { @alias('dataSource.searchString') searchTerm; fuzzySearchEnabled = true; + includeFuzzySearchMatches = true; } @classic @@ -169,4 +177,5 @@ class NodeSearch extends EmberObject.extend(Searchable) { @alias('dataSource.searchString') searchTerm; fuzzySearchEnabled = true; + includeFuzzySearchMatches = true; } diff --git a/ui/app/components/global-search/match.js b/ui/app/components/global-search/match.js new file mode 100644 index 000000000..31942201a --- /dev/null +++ b/ui/app/components/global-search/match.js @@ -0,0 +1,30 @@ +import Component from '@ember/component'; +import { tagName } from '@ember-decorators/component'; +import { computed, get } from '@ember/object'; +import { alias } from '@ember/object/computed'; + +@tagName('') +export default class GlobalSearchMatch extends Component { + @alias('match.fuzzySearchMatches.firstObject') firstMatch; + @alias('firstMatch.indices.firstObject') firstIndices; + + @computed('match.name') + get label() { + return get(this, 'match.name') || ''; + } + + @computed('label', 'firstIndices.[]') + get beforeHighlighted() { + return this.label.substring(0, this.firstIndices[0]); + } + + @computed('label', 'firstIndices.[]') + get highlighted() { + return this.label.substring(this.firstIndices[0], this.firstIndices[1] + 1); + } + + @computed('label', 'firstIndices.[]') + get afterHighlighted() { + return this.label.substring(this.firstIndices[1] + 1); + } +} diff --git a/ui/app/mixins/searchable.js b/ui/app/mixins/searchable.js index 193679b32..1f4a9b89a 100644 --- a/ui/app/mixins/searchable.js +++ b/ui/app/mixins/searchable.js @@ -37,6 +37,7 @@ export default Mixin.create({ // Three search modes exactMatchEnabled: true, fuzzySearchEnabled: false, + includeFuzzySearchMatches: false, regexEnabled: true, // Search should reset pagination. Not every instance of @@ -59,6 +60,7 @@ export default Mixin.create({ matchAllTokens: true, maxPatternLength: 32, minMatchCharLength: 1, + includeMatches: this.includeFuzzySearchMatches, keys: this.fuzzySearchProps || [], getFn(item, key) { return get(item, key); @@ -91,7 +93,17 @@ export default Mixin.create({ } if (this.fuzzySearchEnabled) { - results.push(...this.fuse.search(searchTerm)); + let fuseSearchResults = this.fuse.search(searchTerm); + + if (this.includeFuzzySearchMatches) { + fuseSearchResults = fuseSearchResults.map(result => { + const item = result.item; + item.set('fuzzySearchMatches', result.matches); + return item; + }); + } + + results.push(...fuseSearchResults); } if (this.regexEnabled) { diff --git a/ui/app/styles/components.scss b/ui/app/styles/components.scss index 955c3e73d..ae08d6add 100644 --- a/ui/app/styles/components.scss +++ b/ui/app/styles/components.scss @@ -11,7 +11,7 @@ @import './components/exec-button'; @import './components/exec-window'; @import './components/fs-explorer'; -@import './components/global-search-control'; +@import './components/global-search-container'; @import './components/global-search-dropdown'; @import './components/gutter'; @import './components/gutter-toggle'; diff --git a/ui/app/styles/components/global-search-container.scss b/ui/app/styles/components/global-search-container.scss new file mode 100644 index 000000000..47e8dd646 --- /dev/null +++ b/ui/app/styles/components/global-search-container.scss @@ -0,0 +1,68 @@ +.global-search-container { + position: absolute; + width: 100%; + left: 0; + top: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; + + .global-search { + width: 30em; + + @media #{$mq-hidden-gutter} { + width: 20em; + } + + .ember-power-select-trigger { + background: $nomad-green-darker; + border: 0; + + .icon { + margin-top: 1px; + margin-left: 2px; + + fill: white; + opacity: 0.7; + } + + .placeholder { + opacity: 0.7; + display: inline-block; + padding-left: 2px; + transform: translateY(-1px); + font-weight: $weight-semibold; + } + + .shortcut { + position: absolute; + right: 5px; + top: 5px; + bottom: 5px; + width: 1.4rem; + padding-top: 3px; + text-align: center; + opacity: 0.7; + background: $nomad-green-dark; + font-weight: $weight-semibold; + } + + &.ember-power-select-trigger--active { + background: white; + border-color: white; + + .icon { + fill: black; + opacity: 1; + } + } + } + + .ember-basic-dropdown-content-wormhole-origin { + position: absolute; + top: 0; + width: 100%; + } + } +} diff --git a/ui/app/styles/components/global-search-control.scss b/ui/app/styles/components/global-search-control.scss deleted file mode 100644 index e42243b50..000000000 --- a/ui/app/styles/components/global-search-control.scss +++ /dev/null @@ -1,37 +0,0 @@ -.global-search { - width: 30em; - - .ember-power-select-trigger { - background: $nomad-green-darker; - - .icon { - margin-top: 1px; - margin-left: 2px; - - fill: white; - opacity: 0.7; - } - - .placeholder { - opacity: 0.7; - display: inline-block; - padding-left: 2px; - transform: translateY(-1px); - } - - &.ember-power-select-trigger--active { - background: white; - - .icon { - fill: black; - opacity: 1; - } - } - } - - .ember-basic-dropdown-content-wormhole-origin { - position: absolute; - top: 0; - width: 100%; - } -} diff --git a/ui/app/styles/components/global-search-dropdown.scss b/ui/app/styles/components/global-search-dropdown.scss index 4e9c2f5ef..27e503002 100644 --- a/ui/app/styles/components/global-search-dropdown.scss +++ b/ui/app/styles/components/global-search-dropdown.scss @@ -15,6 +15,16 @@ outline: 0; } + // Prevent Safari from disrupting styling, adapted from http://geek.michaelgrace.org/2011/06/webkit-search-input-styling/ + input[type='search'] { + -webkit-appearance: textfield; + } + + input::-webkit-search-decoration, + input::-webkit-search-cancel-button { + display: none; + } + .ember-power-select-options { background: white; padding: 0.35rem; @@ -32,6 +42,10 @@ background: transparentize($blue, 0.8); color: $blue; } + + .highlighted { + font-weight: $weight-semibold; + } } } diff --git a/ui/app/templates/components/global-search/control.hbs b/ui/app/templates/components/global-search/control.hbs index d1f2c5c94..bbfbbfdf2 100644 --- a/ui/app/templates/components/global-search/control.hbs +++ b/ui/app/templates/components/global-search/control.hbs @@ -6,11 +6,12 @@ @search={{perform this.search}} @onChange={{action 'selectOption'}} @onFocus={{action 'openOnClickOrTab'}} + @onClose={{action 'onCloseEvent'}} @dropdownClass="global-search-dropdown" @calculatePosition={{this.calculatePosition}} @searchMessageComponent="global-search/message" @triggerComponent="global-search/trigger" @registerAPI={{action 'storeSelect'}} as |option|> - {{option.name}} + diff --git a/ui/app/templates/components/global-search/match.hbs b/ui/app/templates/components/global-search/match.hbs new file mode 100644 index 000000000..5520cd259 --- /dev/null +++ b/ui/app/templates/components/global-search/match.hbs @@ -0,0 +1,5 @@ +{{#if firstIndices}} + {{beforeHighlighted}}{{highlighted}}{{afterHighlighted}} +{{else}} + {{label}} +{{/if}} diff --git a/ui/app/templates/components/global-search/trigger.hbs b/ui/app/templates/components/global-search/trigger.hbs index aa52b18cd..52ea1bde8 100644 --- a/ui/app/templates/components/global-search/trigger.hbs +++ b/ui/app/templates/components/global-search/trigger.hbs @@ -1,4 +1,7 @@ {{x-icon "search" class="is-small"}} {{#unless select.isOpen}} - Search -{{/unless}} \ No newline at end of file + Jump to +{{/unless}} +{{#if (not (or select.isActive select.isOpen))}} + / +{{/if}} \ No newline at end of file diff --git a/ui/package.json b/ui/package.json index b4158b09f..a811b363c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -87,7 +87,7 @@ "ember-moment": "^7.8.1", "ember-overridable-computed": "^1.0.0", "ember-page-title": "^5.0.2", - "ember-power-select": "^3.0.4", + "ember-power-select": "backspace/ember-power-select#setIsActiveAPI", "ember-qunit": "^4.4.1", "ember-qunit-nice-errors": "^1.2.0", "ember-resolver": "^5.0.1", diff --git a/ui/tests/acceptance/search-test.js b/ui/tests/acceptance/search-test.js index 3a8240223..ebe443e23 100644 --- a/ui/tests/acceptance/search-test.js +++ b/ui/tests/acceptance/search-test.js @@ -102,6 +102,36 @@ module('Acceptance | search', function(hooks) { clock.restore(); }); + test('search highlights matching substrings', async function(assert) { + server.create('node', { name: 'xyz' }); + + server.create('job', { id: 'traefik', namespaceId: 'default' }); + server.create('job', { id: 'tracking', namespace: 'default' }); + + await visit('/'); + + await selectSearch(PageLayout.navbar.search.scope, 'trae'); + + PageLayout.navbar.search.as(search => { + search.groups[0].as(jobs => { + assert.equal(jobs.options[0].text, 'traefik'); + assert.equal(jobs.options[0].highlighted, 'trae'); + + assert.equal(jobs.options[1].text, 'tracking'); + assert.equal(jobs.options[1].highlighted, 'tra'); + }); + }); + + await selectSearch(PageLayout.navbar.search.scope, 'ra'); + + PageLayout.navbar.search.as(search => { + search.groups[0].as(jobs => { + assert.equal(jobs.options[0].highlighted, 'ra'); + assert.equal(jobs.options[1].highlighted, 'ra'); + }); + }); + }); + test('clicking the search field starts search immediately', async function(assert) { await visit('/'); diff --git a/ui/tests/pages/layout.js b/ui/tests/pages/layout.js index 315646aae..bbb05501f 100644 --- a/ui/tests/pages/layout.js +++ b/ui/tests/pages/layout.js @@ -25,6 +25,7 @@ export default create({ options: collection('.ember-power-select-option', { label: text(), + highlighted: text('.highlighted'), }), }), diff --git a/ui/tests/unit/mixins/searchable-test.js b/ui/tests/unit/mixins/searchable-test.js index 6596d0b90..5dbc4eaf8 100644 --- a/ui/tests/unit/mixins/searchable-test.js +++ b/ui/tests/unit/mixins/searchable-test.js @@ -95,6 +95,39 @@ module('Unit | Mixin | Searchable', function(hooks) { ); }); + test('the fuzzy search can include match results', function(assert) { + const subject = this.subject(); + subject.set('source', [ + EmberObject.create({ id: '1', name: 'United States of America', continent: 'North America' }), + EmberObject.create({ id: '2', name: 'Canada', continent: 'North America' }), + EmberObject.create({ id: '3', name: 'Mexico', continent: 'North America' }), + ]); + + subject.set('fuzzySearchEnabled', true); + subject.set('includeFuzzySearchMatches', true); + subject.set('searchTerm', 'Ameerica'); + assert.deepEqual( + subject + .get('listSearched') + .map(object => object.getProperties('id', 'name', 'continent', 'fuzzySearchMatches')), + [ + { + id: '1', + name: 'United States of America', + continent: 'North America', + fuzzySearchMatches: [ + { + indices: [[2, 2], [4, 4], [9, 9], [11, 11], [17, 23]], + value: 'United States of America', + key: 'name', + }, + ], + }, + ], + 'America is matched due to fuzzy matching' + ); + }); + test('the exact match search mode can be disabled', function(assert) { const subject = this.subject(); subject.set('source', [ diff --git a/ui/yarn.lock b/ui/yarn.lock index f90cf1b36..6c8a4c0f8 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2053,7 +2053,7 @@ ember-cli-typescript "^2.0.2" heimdalljs "^0.3.0" -"@ember-decorators/component@^6.1.0", "@ember-decorators/component@^6.1.1": +"@ember-decorators/component@^6.0.0", "@ember-decorators/component@^6.1.0", "@ember-decorators/component@^6.1.1": version "6.1.1" resolved "https://registry.yarnpkg.com/@ember-decorators/component/-/component-6.1.1.tgz#b360dc4fa8e576ee1c840879399ef1745fd96e06" integrity sha512-Cj8tY/c0MC/rsipqsiWLh3YVN72DK92edPYamD/HzvftwzC6oDwawWk8RmStiBnG9PG/vntAt41l3S7HSSA+1Q== @@ -2076,6 +2076,11 @@ dependencies: ember-cli-babel "^7.1.3" +"@ember/edition-utils@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ember/edition-utils/-/edition-utils-1.2.0.tgz#a039f542dc14c8e8299c81cd5abba95e2459cfa6" + integrity sha512-VmVq/8saCaPdesQmftPqbFtxJWrzxNGSQ+e8x8LLe3Hjm36pJ04Q8LeORGZkAeOhldoUX9seLGmSaHeXkIqoog== + "@ember/optional-features@^0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@ember/optional-features/-/optional-features-0.7.0.tgz#f65a858007020ddfb8342f586112750c32abd2d9" @@ -2098,10 +2103,10 @@ ember-cli-babel "^6.16.0" ember-compatibility-helpers "^1.1.1" -"@ember/render-modifiers@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-1.0.1.tgz#a85e746e4bb9fd51302cc43e726e2c641261a7c2" - integrity sha512-HHZwL84jCVAaIDFtPZHAnM41aB8XgvDiutD1tKnll43fw7/rhejGj/LDWdB1jrPF+vryFSSQwSJ85gk4J7W86g== +"@ember/render-modifiers@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz#2e87c48db49d922ce4850d707215caaac60d8444" + integrity sha512-6tEnHl5+62NTSAG2mwhGMFPhUrJQjoVqV+slsn+rlTknm2Zik+iwxBQEbwaiQOU1FUYxkS8RWcieovRNMR8inQ== dependencies: ember-cli-babel "^7.10.0" ember-modifier-manager-polyfill "^1.1.0" @@ -4133,6 +4138,11 @@ babel-plugin-htmlbars-inline-precompile@^1.0.0: resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-1.0.0.tgz#a9d2f6eaad8a3f3d361602de593a8cbef8179c22" integrity sha512-4jvKEHR1bAX03hBDZ94IXsYCj3bwk9vYsn6ux6JZNL2U5pvzCWjqyrGahfsGNrhERyxw8IqcirOi9Q6WCo3dkQ== +babel-plugin-htmlbars-inline-precompile@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-3.1.0.tgz#85085b50385277f2b331ebd54e22fa91aadc24e8" + integrity sha512-ar6c4YVX6OV7Dzpq7xRyllQrHwVEzJf41qysYULnD6tu6TS+y1FxT2VcEvMC6b9Rq9xoHMzvB79HO3av89JCGg== + babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.4.5: version "2.6.1" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.1.tgz#41f7ead616fc36f6a93180e89697f69f51671181" @@ -5302,6 +5312,11 @@ broccoli-module-unification-reexporter@^1.0.0: mkdirp "^0.5.1" walk-sync "^0.3.2" +broccoli-node-api@^1.6.0, broccoli-node-api@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz#391aa6edecd2a42c63c111b4162956b2fa288cb6" + integrity sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw== + broccoli-node-info@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/broccoli-node-info/-/broccoli-node-info-1.1.0.tgz#3aa2e31e07e5bdb516dd25214f7c45ba1c459412" @@ -5312,6 +5327,13 @@ broccoli-node-info@^2.1.0: resolved "https://registry.yarnpkg.com/broccoli-node-info/-/broccoli-node-info-2.1.0.tgz#ca84560e8570ff78565bea1699866ddbf58ad644" integrity sha512-l6qDuboJThHfRVVWQVaTs++bFdrFTP0gJXgsWenczc1PavRVUmL1Eyb2swTAXXMpDOnr2zhNOBLx4w9AxkqbPQ== +broccoli-output-wrapper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/broccoli-output-wrapper/-/broccoli-output-wrapper-2.0.0.tgz#f1e0b9b2f259a67fd41a380141c3c20b096828e6" + integrity sha512-V/ozejo+snzNf75i/a6iTmp71k+rlvqjE3+jYfimuMwR1tjNNRdtfno+NGNQB2An9bIAeqZnKhMDurAznHAdtA== + dependencies: + heimdalljs-logger "^0.1.10" + broccoli-persistent-filter@^1.1.5, broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.4.3: version "1.4.6" resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.6.tgz#80762d19000880a77da33c34373299c0f6a3e615" @@ -5400,6 +5422,19 @@ broccoli-plugin@^2.0.0: rimraf "^2.3.4" symlink-or-copy "^1.1.8" +broccoli-plugin@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-3.1.0.tgz#54ba6dd90a42ec3db5624063292610e326b1e542" + integrity sha512-7w7FP8WJYjLvb0eaw27LO678TGGaom++49O1VYIuzjhXjK5kn2+AMlDm7CaUFw4F7CLGoVQeZ84d8gICMJa4lA== + dependencies: + broccoli-node-api "^1.6.0" + broccoli-output-wrapper "^2.0.0" + fs-merger "^3.0.1" + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.1.8" + broccoli-rollup@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/broccoli-rollup/-/broccoli-rollup-2.1.1.tgz#0b77dc4b7560a53e998ea85f3b56772612d4988d" @@ -7438,16 +7473,16 @@ ember-auto-import@^1.2.19, ember-auto-import@^1.2.21: walk-sync "^0.3.3" webpack "~4.28" -ember-basic-dropdown@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-2.0.5.tgz#72a8a9c1196d5f84f6b849aa21c3cf8ea7830668" - integrity sha512-wG7v9uk5uIozLFx919Wa40xmLXE5jL1d+HKkUxWQJ1vqZCh8S7MjmYIAuluxNFfegEnCtLd+9iDSdZzEEwTtPg== +ember-basic-dropdown@^2.0.0: + version "2.0.15" + resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-2.0.15.tgz#f86600cfa22ff67de6599fcfb701ad851cc3c6a0" + integrity sha512-gRUCoFLZJ+qu758xDZpfE20LtBRRZWOShtGrPPd18iuseK+6SLkM/uzsL+nANQp3F8hD9kW+aLjsK7E8Khd2Wg== dependencies: "@ember-decorators/component" "^6.1.0" - "@ember/render-modifiers" "^1.0.0" + "@ember/render-modifiers" "^1.0.2" ember-cli-babel "^7.11.0" - ember-cli-htmlbars "^3.1.0" - ember-element-helper "^0.1.1" + ember-cli-htmlbars "^4.0.8" + ember-element-helper "^0.2.0" ember-maybe-in-element "^0.4.0" ember-truth-helpers "2.1.0" @@ -7720,6 +7755,26 @@ ember-cli-htmlbars@^3.0.1, ember-cli-htmlbars@^3.1.0: json-stable-stringify "^1.0.1" strip-bom "^3.0.0" +ember-cli-htmlbars@^4.0.8: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-4.3.1.tgz#4af8adc21ab3c4953f768956b7f7d207782cb175" + integrity sha512-CW6AY/yzjeVqoRtItOKj3hcYzc5dWPRETmeCzr2Iqjt5vxiVtpl0z5VTqHqIlT5fsFx6sGWBQXNHIe+ivYsxXQ== + dependencies: + "@ember/edition-utils" "^1.2.0" + babel-plugin-htmlbars-inline-precompile "^3.0.1" + broccoli-debug "^0.6.5" + broccoli-persistent-filter "^2.3.1" + broccoli-plugin "^3.1.0" + common-tags "^1.8.0" + ember-cli-babel-plugin-helpers "^1.1.0" + fs-tree-diff "^2.0.1" + hash-for-dep "^1.5.1" + heimdalljs-logger "^0.1.10" + json-stable-stringify "^1.0.1" + semver "^6.3.0" + strip-bom "^4.0.0" + walk-sync "^2.0.2" + ember-cli-import-polyfill@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ember-cli-import-polyfill/-/ember-cli-import-polyfill-0.2.0.tgz#c1a08a8affb45c97b675926272fe78cf4ca166f2" @@ -8113,10 +8168,10 @@ ember-decorators@^6.1.1: "@ember-decorators/object" "^6.1.1" ember-cli-babel "^7.7.3" -ember-element-helper@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.1.1.tgz#ffd2a0566b22a13c0e7780ae96443f4ffda2e63d" - integrity sha512-MfES7MbZ5UcHTo1lutJCcz6hI+/CadurWcOR3kOQl0jKcBKdAWyYIJXK4u0FDXzlgKczX9vL3R2eJUtnGe144w== +ember-element-helper@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.2.0.tgz#eacdf4d8507d6708812623206e24ad37bad487e7" + integrity sha512-/WV0PNLyxDvLX/YETb/8KICFTr719OYqFWXqV5XUkh9YhhBGDU/mr1OtlQaWOlsx+sHm42HD2UAICecqex8ziw== dependencies: ember-cli-babel "^6.16.0" @@ -8276,14 +8331,13 @@ ember-page-title@^5.0.2: ember-cli-htmlbars "^3.0.1" ember-copy "^1.0.0" -ember-power-select@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ember-power-select/-/ember-power-select-3.0.4.tgz#52700ecaa2053b0a20b4e5d0a6e63802346e52ad" - integrity sha512-+KS8GnKUuqsC725Ncv3NDz/fbVSYBFkRHPXYTtGSWUtpTkaY2ncSwBr6mIFPDNOr7isBvtUArXHvHCnz5O9xaQ== +ember-power-select@backspace/ember-power-select#setIsActiveAPI: + version "3.0.3" + resolved "https://codeload.github.com/backspace/ember-power-select/tar.gz/6846232f09e9b42d435162134e9055028e0cff8b" dependencies: - "@ember-decorators/component" "^6.1.0" - ember-basic-dropdown "^2.0.5" - ember-cli-babel "^7.11.0" + "@ember-decorators/component" "^6.0.0" + ember-basic-dropdown "^2.0.0" + ember-cli-babel "^7.8.0" ember-cli-htmlbars "^3.1.0" ember-concurrency "^1.0.0" ember-text-measurer "^0.5.0" @@ -9547,6 +9601,18 @@ fs-extra@^8.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-merger@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fs-merger/-/fs-merger-3.1.0.tgz#f30f74f6c70b2ff7333ec074f3d2f22298152f3b" + integrity sha512-RZ9JtqugaE8Rkt7idO5NSwcxEGSDZpLmVFjtVQUm3f+bWun7JAU6fKyU6ZJUeUnKdJwGx8uaro+K4QQfOR7vpA== + dependencies: + broccoli-node-api "^1.7.0" + broccoli-node-info "^2.1.0" + fs-extra "^8.0.1" + fs-tree-diff "^2.0.1" + rimraf "^2.6.3" + walk-sync "^2.0.2" + fs-minipass@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" @@ -15484,6 +15550,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -16416,6 +16487,15 @@ walk-sync@^1.0.0, walk-sync@^1.1.3: ensure-posix-path "^1.1.0" matcher-collection "^1.1.1" +walk-sync@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-2.1.0.tgz#e214248e5f5cf497ddd87db5a2a02e47e29c6501" + integrity sha512-KpH9Xw64LNSx7/UI+3guRZvJWlDxVA4+KKb/4puRoVrG8GkvZRxnF3vhxdjgpoKJGL2TVg1OrtkXIE/VuGPLHQ== + dependencies: + "@types/minimatch" "^3.0.3" + ensure-posix-path "^1.1.0" + matcher-collection "^2.0.0" + walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"