Skip to content

Commit 674151c

Browse files
authored
MBS-11609: Show genre disambiguation on autocomplete dropdown (metabrainz#2088)
Rather than just showing the value as the label, this defines specific labels for the genres - just the name in most cases, but when there's a disambiguation comment we show it too. It won't be actually added to the tag list since it's not part of the value. jQuery Autocomplete doesn't really support HTML labels by default, took the code for that from https://stackoverflow.com/questions/3488016/using-html-in-jquery-ui-autocomplete which seems to just take it from an extension last updated in 2013. Given that fact, we might as well just skip the extension.
1 parent 8941404 commit 674151c

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

root/static/scripts/common/components/TagEditor.js

+30-6
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
* later version: http://www.gnu.org/licenses/gpl-2.0.txt
88
*/
99

10+
import he from 'he';
1011
import * as React from 'react';
1112

1213
import hydrate, {minimalEntity} from '../../../../utility/hydrate';
1314
import loopParity from '../../../../utility/loopParity';
1415
import {unwrapNl} from '../i18n';
1516
import {keyBy, sortByNumber} from '../utility/arrays';
16-
import bracketed from '../utility/bracketed';
17+
import bracketed, {bracketedText} from '../utility/bracketed';
1718
import {compareStrings} from '../utility/compare';
1819
import debounce from '../utility/debounce';
1920
import isBlank from '../utility/isBlank';
@@ -37,6 +38,18 @@ const cmpTags = (a, b) => (
3738
(b.count - a.count) || compareStrings(a.tag.name, b.tag.name)
3839
);
3940

41+
function formatGenreLabel(genre) {
42+
let output = he.encode(genre.name);
43+
if (genre.comment) {
44+
output += (
45+
'<span class="small"> ' +
46+
he.encode(bracketedText(genre.comment)) +
47+
'</span>'
48+
);
49+
}
50+
return output;
51+
}
52+
4053
function getTagsPath(entity) {
4154
const type = entity.entityType.replace('_', '-');
4255
return `/${type}/${entity.gid}/tags`;
@@ -211,7 +224,7 @@ class TagEditor extends React.Component<TagEditorProps, TagEditorState> {
211224

212225
genreMap: {+[genreName: string]: GenreT, ...};
213226

214-
genreNames: $ReadOnlyArray<string>;
227+
genreOptions: $ReadOnlyArray<{+label: string, +value: string}>;
215228

216229
handleSubmit: (SyntheticEvent<HTMLFormElement>) => void;
217230

@@ -235,7 +248,14 @@ class TagEditor extends React.Component<TagEditorProps, TagEditorState> {
235248
this.setTagsInput = this.setTagsInput.bind(this);
236249

237250
this.genreMap = props.genreMap ?? {};
238-
this.genreNames = Object.keys(this.genreMap);
251+
this.genreOptions =
252+
((Object.values(this.genreMap): any): $ReadOnlyArray<GenreT>)
253+
.map(genre => {
254+
return {
255+
label: formatGenreLabel(genre),
256+
value: genre.name,
257+
};
258+
});
239259

240260
this.pendingVotes = new Map();
241261
this.debouncePendingVotes = debounce(
@@ -451,15 +471,19 @@ class TagEditor extends React.Component<TagEditorProps, TagEditorState> {
451471
const filteredTerms: $ReadOnlyArray<string> =
452472
sortByNumber(
453473
$.ui.autocomplete.filter(
454-
self.genreNames.filter(x => !previousTerms.has(x)),
474+
self.genreOptions.filter(x => !previousTerms.has(x.value)),
455475
last,
456476
).sort(),
457-
x => x.startsWith(last) ? 0 : 1,
477+
x => x.value.startsWith(last) ? 0 : 1,
458478
);
459479

460480
response(filteredTerms);
461481
},
462-
});
482+
}).data('ui-autocomplete')._renderItem = function (ul, item) {
483+
return $('<li></li>')
484+
.append('<a>' + item.label + '</a>')
485+
.appendTo(ul);
486+
};
463487

464488
/*
465489
* MBS-9862: jQuery UI disables the browser's builtin autocomplete

0 commit comments

Comments
 (0)