WIP Integrate category search with search box

This commit is contained in:
2026-03-20 18:39:51 +04:00
parent b083c1d001
commit 8e9beb16de
2 changed files with 52 additions and 8 deletions

View File

@@ -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);

View File

@@ -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');
});
}); });