# HG changeset patch # User HIROSE Yuuji # Date 1713666646 -32400 # Node ID 78e904f9be3434bbb9bc0405593669714da3f8ea # Parent 68a01c699acb993fc559b9a64b173c4cb5891f13 Add Filtering by TEAM diff -r 68a01c699acb -r 78e904f9be34 examples/common/default/default.css --- a/examples/common/default/default.css Sat Apr 06 18:08:10 2024 +0900 +++ b/examples/common/default/default.css Sun Apr 21 11:30:46 2024 +0900 @@ -177,9 +177,12 @@ display: inline-block; border-radius: 0.8ex; } td.repl.atall:first-line {font-size: 125%;} +p.filter { /* is located after .blog_replies */ + margin: 0; padding: 0 1ex; +} .blog_replies td.repatt {min-width: 12em;} -.blog_replies td.hideauthor {display: none;} +.blog_replies td.hideauthor, .hide {display: none;} table.blog_replies iframe { width: 80%; min-height: 300px; max-width: 50em; max-height: 80vw; padding: 0; border: 0; diff -r 68a01c699acb -r 78e904f9be34 s4-blog.sh --- a/s4-blog.sh Sat Apr 06 18:08:10 2024 +0900 +++ b/s4-blog.sh Sun Apr 21 11:30:46 2024 +0900 @@ -164,7 +164,12 @@ # blog_m: *article blogowner=`getvalbyid blog owner "$2"` - isgroup "$blogowner" && isgroup=true || isgroup=false + if isgroup "$blogowner"; then + isgroup=true; qgrp=`sqlquote "$blogowner"` + else + isgroup=false + fi + isgrpadmin=false isgrpowner "$user" "$blogowner" && isgrpadmin=true [ x"$user" = x"$blogowner" ] && isgrpadmin=true @@ -197,7 +202,6 @@ *quiz*|*close*|"") # When blog_mode is "", fallback to quiz/close f_exclusive=1 if $isgroup; then - qgrp=`sqlquote "$blogowner"` if $isgrpadmin; then F_UNREADABLE="''" else @@ -278,7 +282,7 @@ hidebtn='' - href4="${blog_math:+Math} $hidebtn 末尾へ" + href4="${blog_math:+Math} $hidebtn 末尾へ" $isgrpadmin && href5=" 読刻" quizmodefile=$tmpd/quiz; rm -f "$quizmodefile" # XXX: Global state @@ -445,7 +449,7 @@ #CAT="tail -n $nlimit" CAT=cat limitedmsg="※最新${nlimit}件のみの表示※" - showalllink="全件表示" + showalllink="全件表示" cat<<-EOF > $omitline :
$limitedmsg
($((narts-$nlimit-1))件省略)
: @@ -649,6 +653,19 @@ title="Shortcut: T${nl}to the Top">先頭へ ${showalllink:+/ `echo $showalllink|sed 's/n:all/&\#bottom/'`$limitedmsg}

EOF + # Put team list + if $usejson && $isgrp; then + echo '' + query<<-EOF + .mode html + SELECT val, json_group_array(b.rowid) mems + FROM grp_mem_m a LEFT JOIN user b ON a.user=b.name + WHERE gname = $qgrp AND key='team' + GROUP BY val; + .mode list + EOF + echo '' + fi $iswritable && cat<<-EOF
diff -r 68a01c699acb -r 78e904f9be34 s4-funcs.sh --- a/s4-funcs.sh Sat Apr 06 18:08:10 2024 +0900 +++ b/s4-funcs.sh Sun Apr 21 11:30:46 2024 +0900 @@ -93,6 +93,7 @@ likeesc=`printf '\037'` # ESCAPE char of LIKE operator iconcachekey="profimgcache_S" asdelim=":::" # delimiter of dumptable td-class specifier +sqlite3 --help 2>&1 | grep -q -- '-json' && usejson=true || usejson=false # Start debug logging logtag="($$)${S4WORLD:+{$S4WORLD\}}" diff -r 68a01c699acb -r 78e904f9be34 s4-main.js --- a/s4-main.js Sat Apr 06 18:08:10 2024 +0900 +++ b/s4-main.js Sun Apr 21 11:30:46 2024 +0900 @@ -8,6 +8,7 @@ mypath = myurl.substring(myurl.lastIndexOf("/")); var art_m_list = []; var mathjax = false; + var filterSelect, filterOption = null; let input_pdfsw = 'input[name="comppdf"]'; if (mypath.match(/(.*)\/(.*)/)) { mypath = RegExp.$2; @@ -304,6 +305,9 @@ newform = new FormData(form); if (data.get("text") > "") { // Called by submit button myform.reset(); + if (filterOption) { // Restore TEAM filterin if any + filterSelect.selectedIndex = filterOption; + } let pdfsw = myform.querySelector(input_pdfsw); if (pdfsw) pdfsw.remove(); // myform.text.value = ''; @@ -839,16 +843,14 @@ let needBOM = e.ctrlKey; if (!blogtbl) return; let trw = blogtbl.querySelector("tr.warn"), a; - if (trw && (a=trw.querySelector("th>a"))) { - if (a.title == "Show All") { - if (window.confirm(`50件以下に表示制限されています。 + if (trw && (a=document.getElementById("showall"))) { + if (window.confirm(`50件以下に表示制限されています。 取得し直しますか? Cancelを押すとこのまま取得します。 Seen articles limited to 50 items. Push OK to get all articles, Cancel to get only seen articles.`)) { - a.click(); - return; - } + a.click(); + return; } } if (navigator.userAgent.match(/Windows/)) { @@ -964,8 +966,8 @@ atMarkView(document); /*****************************************************************/ //(2) Prepare sort - let warn = document.querySelector("tr.warn span.warn"); - if (blogheadtd && warn==null) { + let limit50 = document.getElementById("showall"); + if (blogheadtd && limit50==null) { let umode = "byUser", amode = "byArticle"; let sbtn = document.createElement("button"); sbtn.textContent = umode; @@ -1018,6 +1020,78 @@ sbtn.textContent = uidsort ? amode : umode; }); } + /*****************************************************************/ + //(3) Prepare Filtering by Team + let teamfilter = document.getElementById("team4filter"); + if (blogheadtd && teamfilter) { + let teams = {}; + for (let row of teamfilter.querySelectorAll("tr")) { + let cols = row.querySelectorAll("td"); + if (cols.length == 2) { + // TeamName["user1@dom1","user2@dom2"] + teams[cols[0].textContent] = cols[1].textContent; + } + } + if (Object.keys(teams).length > 0) { + function filterArticles(e) { + if (limit50) { + if (window.confirm(`表示数制限があります。 +全件表示に切り替えますか。Cencel すると限定表示のまま絞り込みます。 +Not all articles are seen. +Push OK to switch to all-articles mode, Cencel to continue without limit.`)) { + limit50.click(); + return; + } + } + let userlist; + try { + userlist = JSON.parse(e.target.value); + } catch (e) { + return; + } + let showall = (userlist == ""); + let tbl = document.querySelector("table.blog_replies"); + for (let row of tbl.querySelectorAll("tr")) { + let author = row.querySelector("a[title]"); + let visible = true; + if (!showall && author) { + let home = author.href; + if (home && home.match(/home\+([0-9]+)/)) { + let uid = RegExp.$1; + visible = userlist.find(e=>e==uid) + } + } + if (visible) + row.classList.remove("hide") + else + row.classList.add("hide") + filterOption = e.target.selectedIndex; + } + + } + // Do Filter Addition + let optall = document.createElement("option"); + filterSelect = document.createElement("select"); + optall.textContent = "-- ALL(全件) --"; + optall.value = '""'; // -> showall=true + filterSelect.appendChild(optall); + filterSelect.addEventListener('change', filterArticles, false) + for (let k in teams) { + let o = document.createElement("option"); + o.textContent = k; + o.value = teams[k]; + filterSelect.appendChild(o); + } + let table = document.querySelector("table.blog_replies"); + if (table) { + let p = document.createElement("p"); + p.textContent = "Filter by TEAM: "; + p.classList.add("filter"); + p.appendChild(filterSelect); + table.insertAdjacentElement('beforebegin', p) + } + } + } } function initGrpAction() { var rev = document.getElementById("reverse");