diff --git a/assets/js/autocomplete.ts b/assets/js/autocomplete.ts index aceb13f4..bc1d1a98 100644 --- a/assets/js/autocomplete.ts +++ b/assets/js/autocomplete.ts @@ -7,7 +7,13 @@ import { getTermContexts } from './match_query'; import store from './utils/store'; import { TermContext } from './query/lex'; import { $$ } from './utils/dom'; -import { fetchLocalAutocomplete, fetchSuggestions, SuggestionsPopup, TermSuggestion } from './utils/suggestions'; +import { + formatLocalAutocompleteResult, + fetchLocalAutocomplete, + fetchSuggestions, + SuggestionsPopup, + TermSuggestion, +} from './utils/suggestions'; let inputField: HTMLInputElement | null = null, originalTerm: string | undefined, @@ -173,7 +179,7 @@ function listenAutocomplete() { const suggestions = localAc .matchPrefix(trimPrefixes(originalTerm), suggestionsCount) - .map(({ name, imageCount }) => ({ label: `${name} (${imageCount})`, value: name })); + .map(formatLocalAutocompleteResult); if (suggestions.length) { popup.renderSuggestions(suggestions).showForField(targetedInput); diff --git a/assets/js/utils/__tests__/suggestions.spec.ts b/assets/js/utils/__tests__/suggestions.spec.ts index 59102d2b..29de9691 100644 --- a/assets/js/utils/__tests__/suggestions.spec.ts +++ b/assets/js/utils/__tests__/suggestions.spec.ts @@ -2,6 +2,7 @@ import { fetchMock } from '../../../test/fetch-mock.ts'; import { fetchLocalAutocomplete, fetchSuggestions, + formatLocalAutocompleteResult, purgeSuggestionsCache, SuggestionsPopup, TermSuggestion, @@ -11,6 +12,7 @@ import path from 'path'; import { LocalAutocompleter } from '../local-autocompleter.ts'; import { afterEach } from 'vitest'; import { fireEvent } from '@testing-library/dom'; +import { getRandomIntBetween } from '../../../test/randomness.ts'; const mockedSuggestionsEndpoint = '/endpoint?term='; const mockedSuggestionsResponse = [ @@ -331,4 +333,35 @@ describe('Suggestions', () => { expect(() => fetchLocalAutocomplete()).rejects.toThrowError('Received error from server'); }); }); + + describe('formatLocalAutocompleteResult', () => { + it('should format suggested tags as tag name and the count', () => { + const tagName = 'safe'; + const tagCount = getRandomIntBetween(5, 10); + + const resultObject = formatLocalAutocompleteResult({ + name: tagName, + aliasName: tagName, + imageCount: tagCount, + }); + + expect(resultObject.label).toBe(`${tagName} (${tagCount})`); + expect(resultObject.value).toBe(tagName); + }); + + it('should display original alias name for aliased tags', () => { + const tagName = 'safe'; + const tagAlias = 'rating:safe'; + const tagCount = getRandomIntBetween(5, 10); + + const resultObject = formatLocalAutocompleteResult({ + name: tagName, + aliasName: tagAlias, + imageCount: tagCount, + }); + + expect(resultObject.label).toBe(`${tagAlias} ⇒ ${tagName} (${tagCount})`); + expect(resultObject.value).toBe(tagName); + }); + }); }); diff --git a/assets/js/utils/suggestions.ts b/assets/js/utils/suggestions.ts index fb810be3..099c9860 100644 --- a/assets/js/utils/suggestions.ts +++ b/assets/js/utils/suggestions.ts @@ -1,7 +1,7 @@ import { makeEl } from './dom.ts'; import { mouseMoveThenOver } from './events.ts'; import { handleError } from './requests.ts'; -import { LocalAutocompleter } from './local-autocompleter.ts'; +import { LocalAutocompleter, Result } from './local-autocompleter.ts'; export interface TermSuggestion { label: string; @@ -175,3 +175,16 @@ export async function fetchLocalAutocomplete(): Promise { .then(resp => resp.arrayBuffer()) .then(buf => new LocalAutocompleter(buf)); } + +export function formatLocalAutocompleteResult(result: Result): TermSuggestion { + let tagName = result.name; + + if (tagName !== result.aliasName) { + tagName = `${result.aliasName} ⇒ ${tagName}`; + } + + return { + value: result.name, + label: `${tagName} (${result.imageCount})`, + }; +}