Exclude trashed items from tag autocomplete suggestions

https://forums.zotero.org/discussion/132875/some-tag-suggestions-appearing-capitalised
This commit is contained in:
Dan Stillman 2026-07-22 11:46:32 -04:00
parent 146520aed5
commit a4b39b91f3
2 changed files with 49 additions and 2 deletions

View file

@ -76,11 +76,14 @@ ZoteroAutoComplete.prototype.startSearch = async function (searchString, searchP
case 'tag':
var sql = "SELECT DISTINCT name AS val, NULL AS id FROM tags WHERE name LIKE ? ESCAPE '\\'";
var sqlParams = [Zotero.DB.escapeSQLExpression(searchString) + '%'];
// Suggest only tags on items that aren't in the trash, optionally scoped by library
sql += " AND tagID IN (SELECT tagID FROM itemTags JOIN items USING (itemID) "
+ "WHERE itemID NOT IN (SELECT itemID FROM deletedItems)";
if (libraryIDs.length) {
sql += " AND tagID IN (SELECT tagID FROM itemTags JOIN items USING (itemID) "
+ `WHERE libraryID IN (${libraryPlaceholders}))`;
sql += ` AND libraryID IN (${libraryPlaceholders})`;
sqlParams.push(...libraryIDs);
}
sql += ")";
if (searchParams.itemID) {
sql += " AND name NOT IN (SELECT name FROM tags WHERE tagID IN ("
+ "SELECT tagID FROM itemTags WHERE itemID = ?))";

View file

@ -341,4 +341,48 @@ describe("Item Tags Box", function () {
await item.eraseTx();
});
});
describe("Tag Autocomplete", function () {
function getTagSuggestions(searchString, params) {
let search = Components.classes["@mozilla.org/autocomplete/search;1?name=zotero"]
.getService(Components.interfaces.nsIAutoCompleteSearch);
return new Promise((resolve) => {
let listener = {
onSearchResult(_, result) {
let status = result.searchResult;
let done = status == Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS
|| status == Components.interfaces.nsIAutoCompleteResult.RESULT_NOMATCH
|| status == Components.interfaces.nsIAutoCompleteResult.RESULT_FAILURE;
if (!done) {
return;
}
let values = [];
for (let i = 0; i < result.matchCount; i++) {
values.push(result.getValueAt(i));
}
resolve(values);
}
};
search.startSearch(searchString, JSON.stringify(params), null, listener);
});
}
it("should not suggest tags only on trashed items", async function () {
var prefix = Zotero.Utilities.randomString().toLowerCase();
var liveTag = prefix + 'live';
var trashedTag = prefix + 'trashed';
await createDataObject('item', { tags: [{ tag: liveTag }] });
var trashed = await createDataObject('item', { tags: [{ tag: trashedTag }] });
trashed.deleted = true;
await trashed.saveTx();
var suggestions = await getTagSuggestions(
prefix, { fieldName: 'tag', libraryID: Zotero.Libraries.userLibraryID }
);
assert.include(suggestions, liveTag);
assert.notInclude(suggestions, trashedTag);
});
});
})