Fix tag hide/show toggle in Tag Management not persisting (#5226) * Initial plan * Fix tag hide/show in Tag Management: pass original tag refs instead of copies, fix inverted tooltip Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Revert unrelated package-lock.json changes Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Revert tooltip change: tooltip shows current state, not action after click Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Pre-calculate tag counts into a Map and pass to sortTags for sort-by-usage Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Revert unintended package-lock.json changes from npm install Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Use instanceof Map for counts checks, add missing JSDoc param for sortTags Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Revert unintended package-lock.json changes Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Remove legacy `count` field * Improve readability (marginally) --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

4fa37e52f731c2aa714d5e52b38945853b591cb8

Copilot <198982749+Copilot@users.noreply.github.com>

Signed
1 files changed, +12 -11Showing whitespace changes
public/scripts/tags.js+12 -11
@@ -326,7 +326,6 @@ const TAG_FOLDER_DEFAULT_TYPE = 'NONE';
326 * @property {string} [folder_type] - The bogus folder type of this tag (based on `TAG_FOLDER_TYPES`)326 * @property {string} [folder_type] - The bogus folder type of this tag (based on `TAG_FOLDER_TYPES`)
327 * @property {string} [filter_state] - The saved state of the filter chosen of this tag (based on `FILTER_STATES`)327 * @property {string} [filter_state] - The saved state of the filter chosen of this tag (based on `FILTER_STATES`)
328 * @property {number} [sort_order] - A custom integer representing the sort order if tags are sorted328 * @property {number} [sort_order] - A custom integer representing the sort order if tags are sorted
329 * @property {number} [count] - The number of entities that have this tag assigned
330 * @property {string} [color] - The background color of the tag329 * @property {string} [color] - The background color of the tag
331 * @property {string} [color2] - The foreground color of the tag330 * @property {string} [color2] - The foreground color of the tag
332 * @property {number} [create_date] - A number representing the date when this tag was created331 * @property {number} [create_date] - A number representing the date when this tag was created
@@ -1764,10 +1763,11 @@ function makeTagListDraggable(tagContainer) {
1764 * Sorts the given tags, returning a shallow copy of it1763 * Sorts the given tags, returning a shallow copy of it
1765 *1764 *
1766 * @param {Tag[]} tags - The tags1765 * @param {Tag[]} tags - The tags
1766 * @param {Map<string, number>} [counts=null] - Optional map of tag ID to usage count
1767 * @returns {Tag[]} The sorted tags1767 * @returns {Tag[]} The sorted tags
1768 */1768 */
1769function sortTags(tags) {1769function sortTags(tags, counts = null) {
1770 return tags.slice().sort(compareTagsForSort);1770 return tags.slice().sort((a, b) => compareTagsForSort(a, b, counts));
1771}1771}
17721772
1773/**1773/**
@@ -1775,15 +1775,18 @@ function sortTags(tags) {
1775 *1775 *
1776 * @param {Tag} a - First tag1776 * @param {Tag} a - First tag
1777 * @param {Tag} b - Second tag1777 * @param {Tag} b - Second tag
1778 * @param {Map<string, number>} [counts=null] - Optional map of tag ID to usage count
1778 * @returns {number} The compare result1779 * @returns {number} The compare result
1779 */1780 */
1780function compareTagsForSort(a, b) {1781function compareTagsForSort(a, b, counts = null) {
1781 // default sort: alphabetical, case insensitive1782 // default sort: alphabetical, case insensitive
1782 const defaultSort = a.name.toLowerCase().localeCompare(b.name.toLowerCase());1783 const defaultSort = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
17831784
1784 // sort on number of entries1785 // sort on number of entries
1785 if (power_user.tag_sort_mode === tag_sort_mode.BY_ENTRIES) {1786 if (power_user.tag_sort_mode === tag_sort_mode.BY_ENTRIES) {
1786 return ((b.count || 0) - (a.count || 0)) || defaultSort;1787 const aCount = counts instanceof Map ? (counts.get(a.id) || 0) : 0;
1788 const bCount = counts instanceof Map ? (counts.get(b.id) || 0) : 0;
1789 return (bCount - aCount) || defaultSort;
1787 }1790 }
17881791
1789 // alphabetical sort1792 // alphabetical sort
@@ -2273,13 +2276,11 @@ function copyTags(data) {
2273function printViewTagList(tagContainer, empty = true) {2276function printViewTagList(tagContainer, empty = true) {
2274 if (empty) tagContainer.empty();2277 if (empty) tagContainer.empty();
2275 const everything = Object.values(tag_map).flat();2278 const everything = Object.values(tag_map).flat();
2276 const tagsWithCounts = tags.map(tag => {2279 const counts = new Map(tags.map(tag => [tag.id, everything.filter(x => x === tag.id).length]));
2277 const count = everything.filter(x => x === tag.id).length;2280 const sortedTags = sortTags(tags, counts);
2278 return { ...tag, count: count };
2279 });
2280 const sortedTags = sortTags(tagsWithCounts);
2281 for (const tag of sortedTags) {2281 for (const tag of sortedTags) {
2282 appendViewTagToList(tagContainer, tag, tag.count);2282 const count = counts.get(tag.id) || 0;
2283 appendViewTagToList(tagContainer, tag, count);
2283 }2284 }
2284}2285}
22852286