« get me outta code hell

client, content, css: group contributions filter notice & clear link - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2026-06-10 07:18:13 -0300
committer(quasar) nebula <qznebula@protonmail.com>2026-06-10 07:20:40 -0300
commitb5cfd785360ced74970b06c9c1e6436bf7281b72 (patch)
tree6fbff6e9930d852aad80247e180af274ec76b897
parent9c946df709fbeca15bc6e76435cbe30269a2bd3a (diff)
client, content, css: group contributions filter notice & clear link
-rw-r--r--src/content/dependencies/generateArtistInfoPageChunkedList.js20
-rw-r--r--src/static/css/features.css5
-rw-r--r--src/static/js/client/group-contributions-table.js44
-rw-r--r--src/strings-default.yaml3
4 files changed, 68 insertions, 4 deletions
diff --git a/src/content/dependencies/generateArtistInfoPageChunkedList.js b/src/content/dependencies/generateArtistInfoPageChunkedList.js
index 54577885..f9db4265 100644
--- a/src/content/dependencies/generateArtistInfoPageChunkedList.js
+++ b/src/content/dependencies/generateArtistInfoPageChunkedList.js
@@ -11,8 +11,24 @@ export default {
     },
   },
 
-  generate: (slots, {html}) =>
+  generate: (slots, {html, language}) =>
     html.tag('dl',
       {[html.onlyIfContent]: true},
-      [slots.groupInfo, slots.chunks]),
+
+      [
+        slots.groupInfo,
+
+        slots.chunks,
+
+        !html.isBlank(slots.groupInfo) &&
+          html.tag('dt', {class: 'filter-notice'},
+            {style: 'display: none'},
+
+            language.encapsulate('artistPage.filterNotice', capsule =>
+              language.$(capsule, {
+                clear:
+                  html.tag('a', {href: '#'},
+                    language.$(capsule, 'clear')),
+              }))),
+      ]),
 };
diff --git a/src/static/css/features.css b/src/static/css/features.css
index f0bd1425..90c297e6 100644
--- a/src/static/css/features.css
+++ b/src/static/css/features.css
@@ -1301,6 +1301,11 @@
       background: var(--primary-color);
     }
   }
+
+  .group-contributions-table ~ .filter-notice a {
+    text-decoration: underline;
+    text-decoration-style: dotted;
+  }
 }
 
 /* Image and media containers */
diff --git a/src/static/js/client/group-contributions-table.js b/src/static/js/client/group-contributions-table.js
index 3b79f84d..80ee38a1 100644
--- a/src/static/js/client/group-contributions-table.js
+++ b/src/static/js/client/group-contributions-table.js
@@ -13,6 +13,9 @@ export const info = {
   chunkDTs: null,
   chunkDDs: null,
   chunkGroupDirectories: null,
+
+  filterNotices: null,
+  filterNoticeClearLinks: null,
 };
 
 export function getPageReferences() {
@@ -38,19 +41,29 @@ export function getPageReferences() {
 
   info.chunkDTs =
     info.lists
-      .map(list => Array.from(list.querySelectorAll('dt')));
+      .map(list => Array.from(list.querySelectorAll('dt')))
+      .map(dts => dts
+        .filter(dt => !dt.classList.contains('filter-notice')));
 
   info.chunkDDs =
     info.chunkDTs
       .map(dts => dts
         .map(dt => dt.nextElementSibling)
-        .map(el => el.tagName === 'DD' ? el : null));
+        .map(el => el?.tagName === 'DD' ? el : null));
 
   info.chunkGroupDirectories =
     info.chunkDTs
       .map(dts => dts
         .map(dt => dt.dataset.groups)
         .map(string => string ? string.split(' ') : []));
+
+  info.filterNotices =
+    info.lists
+      .map(list => list.querySelector('.filter-notice'));
+
+  info.filterNoticeClearLinks =
+    info.filterNotices
+      .map(notice => notice.querySelector('a'));
 }
 
 export function addPageListeners() {
@@ -67,6 +80,16 @@ export function addPageListeners() {
         });
       });
     });
+
+  stitchArrays({
+    table: info.tables,
+    clearLink: info.filterNoticeClearLinks,
+  }).forEach(({table, clearLink}) => {
+      clearLink.addEventListener('click', domEvent => {
+        domEvent.preventDefault();
+        handleClearLinkClicked(table);
+      });
+    });
 }
 
 function handleGroupLinkClicked(table, groupLink) {
@@ -84,6 +107,16 @@ function handleGroupLinkClicked(table, groupLink) {
   updateVisibleChunks(table);
 }
 
+function handleClearLinkClicked(table) {
+  const i = info.tables.indexOf(table);
+
+  for (const link of info.groupLinks[i]) {
+    link.classList.remove('selected');
+  }
+
+  updateVisibleChunks(table);
+}
+
 function updateVisibleChunks(table) {
   const i = info.tables.indexOf(table);
 
@@ -120,4 +153,11 @@ function updateVisibleChunks(table) {
         cssProp(chunkDD, 'display', null);
       }
     });
+
+  const filterNotice = info.filterNotices[i];
+  if (selectedGroupDirectories.length >= 1) {
+    cssProp(filterNotice, 'display', null);
+  } else {
+    cssProp(filterNotice, 'display', 'none');
+  }
 }
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index 9a5f324e..200296f3 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -1950,6 +1950,9 @@ artistPage:
       count.musicVideos: "Music Videos"
       duration: "Duration"
 
+  filterNotice: "(The list above is filtered. {CLEAR})"
+  filterNotice.clear: "Click to stop filtering."
+
   trackList.title: "Tracks"
   artList.title: "Artworks"
   musicVideoList.title: "Music Videos"