WIP Integrate category search with search box
This commit is contained in:
@@ -35,23 +35,26 @@ export default class SearchBoxComponent extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
handleInput(event) {
|
handleInput(event) {
|
||||||
this.query = event.target.value;
|
const value = event.target.value;
|
||||||
|
this.query = value;
|
||||||
if (this.args.onQueryChange) {
|
if (this.args.onQueryChange) {
|
||||||
this.args.onQueryChange(this.query);
|
this.args.onQueryChange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.query.length < 2) {
|
if (value.length < 2) {
|
||||||
this.results = [];
|
this.results = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.searchTask.perform();
|
this.searchTask.perform(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchTask = task({ restartable: true }, async () => {
|
searchTask = task({ restartable: true }, async (term) => {
|
||||||
await timeout(300);
|
await timeout(300);
|
||||||
|
|
||||||
if (this.query.length < 2) return;
|
const query = typeof term === 'string' ? term : this.query;
|
||||||
|
|
||||||
|
if (query.length < 2) return;
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
try {
|
try {
|
||||||
@@ -62,7 +65,7 @@ export default class SearchBoxComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter categories
|
// Filter categories
|
||||||
const q = this.query.toLowerCase();
|
const q = query.toLowerCase();
|
||||||
const categoryMatches = POI_CATEGORIES.filter((c) =>
|
const categoryMatches = POI_CATEGORIES.filter((c) =>
|
||||||
c.label.toLowerCase().includes(q)
|
c.label.toLowerCase().includes(q)
|
||||||
).map((c) => ({
|
).map((c) => ({
|
||||||
@@ -72,7 +75,7 @@ export default class SearchBoxComponent extends Component {
|
|||||||
icon: 'search',
|
icon: 'search',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const results = await this.photon.search(this.query, lat, lon);
|
const results = await this.photon.search(query, lat, lon);
|
||||||
this.results = [...categoryMatches, ...results];
|
this.results = [...categoryMatches, ...results];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Search failed', e);
|
console.error('Search failed', e);
|
||||||
|
|||||||
@@ -134,4 +134,45 @@ module('Integration | Component | search-box', function (hooks) {
|
|||||||
|
|
||||||
assert.verifySteps(['search: cafe, 52.52, 13.405']);
|
assert.verifySteps(['search: cafe, 52.52, 13.405']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('it allows typing even when controlled by parent with a query argument', async function (assert) {
|
||||||
|
class MockPhotonService extends Service {
|
||||||
|
async search() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.owner.register('service:photon', MockPhotonService);
|
||||||
|
|
||||||
|
this.query = '';
|
||||||
|
this.updateQuery = (val) => {
|
||||||
|
this.set('query', val);
|
||||||
|
};
|
||||||
|
this.noop = () => {};
|
||||||
|
|
||||||
|
await render(
|
||||||
|
<template>
|
||||||
|
<SearchBox
|
||||||
|
@query={{this.query}}
|
||||||
|
@onQueryChange={{this.updateQuery}}
|
||||||
|
@onToggleMenu={{this.noop}}
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initial state
|
||||||
|
assert.dom('.search-input').hasValue('');
|
||||||
|
|
||||||
|
// Simulate typing
|
||||||
|
await fillIn('.search-input', 't');
|
||||||
|
assert.dom('.search-input').hasValue('t', 'Input should show "t"');
|
||||||
|
|
||||||
|
await fillIn('.search-input', 'te');
|
||||||
|
assert.dom('.search-input').hasValue('te', 'Input should show "te"');
|
||||||
|
|
||||||
|
// Simulate external update (e.g. chip click)
|
||||||
|
this.set('query', 'restaurant');
|
||||||
|
// wait for re-render
|
||||||
|
await click('.search-input'); // just to trigger a change cycle or ensure stability
|
||||||
|
assert.dom('.search-input').hasValue('restaurant', 'Input should update from external change');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user