From 73fdda4a7fc9dd3c39149296ca8d45421aa0ea55 Mon Sep 17 00:00:00 2001 From: Pontoporeia Date: Tue, 21 Apr 2026 19:05:18 +0200 Subject: [PATCH] fix repertoire AP/OR/FI columns and main scroll containment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - repertoire-index.php: add $colHasMatches per-column guard. Entries in a column are only faded when that column has at least one matched entry in the current result set. When a dimension has no matched entries (e.g. no thesis has orientation_id set yet), the entire column stays fully interactive — all values remain clickable. This fixes: empty columns, forced single-select, cascade fading. - Database.php: revert allAp/allOr/allFi to full lookup-table queries so all known values are always shown (not just ones linked to theses). - common.css: body is now a flex column; main gets flex:1 + min-height:0; header-search-wrap gets flex-shrink:0; duplicate html/body blocks merged. - public.css: removed redundant top-level main block; home-main gets min-height:0. - repertoire.css: search-main gets min-height:0 for proper flex scroll. --- .gitignore | 7 ++---- TODO.md | 16 +++++++++---- app/public/assets/css/common.css | 15 +++++------- app/public/assets/css/public.css | 8 +------ app/public/assets/css/repertoire.css | 1 + .../f528764d624db129b32c21fbca0cb8d6.json | 1 - app/storage/test.db | Bin 282624 -> 286720 bytes app/templates/partials/repertoire-index.php | 22 ++++++++++++++---- 8 files changed, 38 insertions(+), 32 deletions(-) delete mode 100644 app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json diff --git a/.gitignore b/.gitignore index 003c518..b9eb6b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,13 @@ -# Admin credentials (contains bcrypt hash — never commit) -config/admin_credentials.php - # Vendor directory (third-party code) vendor/ compose.lock ### Test databases ### -storage/test.db +app/storage/test.db ### Logs ### error.log -storage/cache/ +app/storage/cache/ # Nix .direnv/ diff --git a/TODO.md b/TODO.md index d445ce3..9126b2d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,13 @@ # TODO -## Fix repertoire.php -- [ ] Fix AP and orientation columns not working like other columns -- [ ] Make main element scrollable instead of body -- [ ] Update public.css (general) -- [ ] Update repertoire.css (page-specific) +## Répertoire page fixes +- [x] Fix AP and orientation columns returning empty results when clicked +- [x] Fix multi-select being blocked (only one entry selectable at a time) +- [x] Fix all other columns becoming faded when AP/OR filter is selected +- [x] Always show all lookup-table values (ap/or/fi); only fade based on cross-dimension matched data when the column has at least one matched entry (`$colHasMatches` guard) +- [x] Make `main` the scrollable element instead of body + - [x] `common.css`: body is now `display:flex; flex-direction:column`, `main` gets `flex:1; min-height:0` + - [x] `public.css`: removed redundant `main` block, `.home-main` keeps its `overflow-y:auto` + - [x] `repertoire.css`: `.search-main` gets `min-height:0` for proper flex scroll containment + - [x] `common.css`: `.header-search-wrap` gets `flex-shrink:0` +- [x] `Database::getRepertoireFilterData`: `allAp`, `allOr`, `allFi` now sourced from actual published thesis joins (not bare lookup tables), matching the pattern used by years and keywords diff --git a/app/public/assets/css/common.css b/app/public/assets/css/common.css index e560856..bcd6bfb 100644 --- a/app/public/assets/css/common.css +++ b/app/public/assets/css/common.css @@ -11,6 +11,7 @@ body { margin: 0; padding: 0; height: 100%; + overflow: hidden; } body { @@ -22,13 +23,8 @@ body { rgba(0, 0, 0, 0) 92%, rgba(149, 87, 181, 1) 100% ); -} - -html, -body { - margin: 0; - height: 100%; - overflow: hidden; + display: flex; + flex-direction: column; } a { @@ -132,7 +128,8 @@ body > header nav ul a[aria-current="page"] { } main { - overflow: scroll; + flex: 1; + min-height: 0; } /* ============================================================ @@ -140,8 +137,8 @@ main { ============================================================ */ .header-search-wrap { padding: 0 0; + flex-shrink: 0; background-color: var(--gradient-4); - background: linear-gradient(180deg, var(--gradient-4) 0%, #ffffffee 100%); } diff --git a/app/public/assets/css/public.css b/app/public/assets/css/public.css index c4237cd..d40c878 100644 --- a/app/public/assets/css/public.css +++ b/app/public/assets/css/public.css @@ -4,16 +4,10 @@ @import url("./variables.css"); -main { - display: flex; - flex-direction: column; - min-height: 100vh; - overflow: hidden; -} - /* Cards grid — scrollable main area */ .home-main { flex: 1; + min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 0; diff --git a/app/public/assets/css/repertoire.css b/app/public/assets/css/repertoire.css index e19a446..ec9b7f2 100644 --- a/app/public/assets/css/repertoire.css +++ b/app/public/assets/css/repertoire.css @@ -6,6 +6,7 @@ .search-main { flex: 1; + min-height: 0; overflow-y: auto; overflow-x: hidden; } diff --git a/app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json b/app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json deleted file mode 100644 index 65c84ca..0000000 --- a/app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json +++ /dev/null @@ -1 +0,0 @@ -[1777059009,1777059010,1777059010,1777059010,1777059010,1777059010,1777059010,1777059010,1777059011,1777059011,1777059011,1777059011,1777059011,1777059011,1777059011,1777059011,1777059011,1777059011,1777059012,1777059012,1777059012,1777059012,1777059013,1777059013,1777059013,1777059013,1777059013,1777059013,1777059013,1777059013] \ No newline at end of file diff --git a/app/storage/test.db b/app/storage/test.db index 01fe6ed571f1aa9bdcd54060873f8d17e98dcd32..6e84cee897e32eecb80920461f89495f0ab6eb87 100644 GIT binary patch delta 4646 zcmeHLTWl0n7(UaP?X;aa=X60rptPM*+fqtP+c6Yd3tMOlr5772M1=>YyVG`Xc4wX0 ztwM}LG|^}xDm7>{Dj`I>T#{-HeG)LM1dNH7@ZgOEn|R@c%LBg1gXiqj?shpqNlbjP zUuLuC%s>DC{r~yDb9TD#kbmD9|7%6C4FJ$dt`2euudit0+CJKK1TU539)M5a?N~%d z(N1^;9)PX#Z}J;*&tzF)o$Pi>A}C(1s(Fv=VWn-a9@gr}MmoY&8nEIq)3Tn(^61{d z<+gkg)T}2idoA10BD%8G2##oWDC`aEY;PDC4r_*)<@XM52l7Nv-Adf{X-;r#OYypb zbYf!%innGCuM~$ehdWE!Glxe@1~P|YX-DR8dueax@I+}>#_(gM6stvfh+o9Tv|*Mx=+wAv&8dV*LB@@vRTEsppdCX)iAY-bv&<7e+wOg|- z(}-xwz^FB7g{)DHVau2bU>|UsRJCo7HKKIe$%N7#4~`@c$8=MVG3*&r%_zlwyJnJp zGIXWi&|@*3VaS;3fC|moH|%+)(jxmnt*UNL zCd}kGDdGm*j*w1dM9rEKs9Yv@x4wOt@AJVi@lv=xZ%1Bh-V*Vm_^J4g_>4Fp){7|j zdhS=b$8%rK4dyoG`h8b?=Y2bynN@ZRq-`8+)G};GaSS&WPbM5j$nq_e zSJ0{rk_FacY+mJE)Tm#Jo0if^%gzc}wwaP2)J;<%JI@nygSp=b}XtU~c%%0vm;M$C9J&Wc*mLF*B<;xtnwRHY3YHX}_}X%|2#$vb!!B$LnWl57O7Nt@`XR172Q6m5};}HJvxhy zqj%9uaDntJ+JknXZSYa}Fr1byqs_P%t-)8JAdkzd@Go*P{91Yyo`oGU#sU1cJS1O} z!qQK0O1dGxhrfXz!j-rQzk*#{jf>zxIahvM>O|GB6e-9r_h5vFF@P`P&*c43c}hBm zeDcpylRSZUz`vx&@HiZj+oVc#174FRq^Yt1|9rvNH}4B>=1$Rv_%bfNEA%eltGT&5 zK+i(HhD)nGCHC$@zJkjX_7*ykDdH~bH!axBe!hyE(WdK(bJJp8B~!Nuv6E7mE4mKI zmy&QZ`f8Wxq33C7qempIn+k9ZKT&g&F zD}8#leIKF`XIizTiXY(S(U#4aoZ1;3_+UQ2m`inA{#ub=NP{;`PTYKi|G#to@0>Xs z+I%`^YC`7vH!gtmM_?fU;tv$~I=(*T59D0IC8^(sNVP%%$Va$YQMtQl^8~pM=L)AP(Px|+5$L>FQ!M*Ugy8|uwmr-*M4pW3r z*5?QTZ|Ns7#ksl2Ui$Nxfo!93%s{r$9n_Q7MG{kdM{qHXY)@yghaYhUvW*zD@%aoR z37rDy6uN+G@G-m}$M6^E8u=B_jenhNP!6H~Mf_^+mUncih;QL;^R``3%&+He`_7#I zCc2vQr&svXn1KvxDLI|N6tof<@Qh}g4i)_;sJVx*b5(+tq2=?ye)R96<{sRo2-AIN lN~q^=UZrQiRXn8xaxUSq`ogu4C#MAc|IbEpwP)Qe{u}rl=8FIT delta 11808 zcmd5?3v?V;d0y?z-CeD;b0xoDvPOQ%4{7zXWhaesf@6Zg#%>%OXw!z#?(AyB?#yOp zN0Cd*1R81{1=5HEO-?zuIXT1%uMpFOM+(H7h7!snDFs4P9x0Ew1(MPb+Q4c1{r{a^ zZGsJ@r#+`SNB7sx1x}Zo_Y17rMt?jVF z`ZO+Q=C2&NdrenvCLte?ei&%GjdB=@-SVtLq@luzb# z`R&{na}VYY$V=s|-B0E2m0!x;k=rhJ%eTr%Zj)W*D*dizH@kV z=R{`l!^C8I@x%CJD*mu*cyx49w0*cpZ~L%IYx^*s?9%!=F*Ut2aZjy7Hl$VA|H}xp~ju^cq*fJbaZAisWi!SI+Y@sN~HuzAyPU?T~BEwH7%7SnZ&4f zc6KTg8wnWyukxSeKgz$Ce=9#H8<_ij@^@&;j!Y)QGL0YljHy`)Az13V&QjAfmPyP_ zQ|I8lZn-ugpOlZu&&t1$x5>B3*T`vkmAp*m<=Qj7wVxSLZ+8mn^k*_%HQ%dxbvyKX zyVRw0cJWeHT}pMfE-mTArH=lL$Ru0WdNb-VkzTx%R+sct>(Y{xdQ%h0TGU!psOL0o z@i|>Rm(<%<(9~ne#m9P+sZLTPx%iaqNWlU9nbuU~=5BdAx%p}N1Nj|za{%P5q^AYg! z0mXUIsezZ8fTkVkB&(VdP!*F3=-QzR0cAThe1J#_sEZ|ZsM{e3icWc70(^hA#dw0^ zKFobv69Y~8I-OLi$F7FX>{`svQWLSOg>toqr8?m%qW&J^we7xsO#Yqxg8U59$H(N| z@_q7l`EL16`F8n6`8xS~GLRK%%ion(%e_aD*Iy`qL++Hra*OPjt7NatO3nDW@e|`m z#`leH8IKx|7@sp9F#giG$M}$O+W2$hR%71yW8)3RYf%AGMkMyY>dB1Q4Y4aDCLwla z#4d=5jMxb=o)HreV`(uCF`5=*5F=?Z3XxBX5s2Zm$U_XJ#4yB;lo*28o)SACwxz^& zh^;BH4Pr1QwnA)4i9v|XDG_af+>{cVAvOxJ31Wi~8zBaS*Z|Qh!~jH(5GI5vL_b8o z5bGh<3(*JBC&W64bwaF#SgVUQ5NmX?8e+9BRza-N#Y%{kx>y0RLKn*+mg{0!1i4HX zOCgr(VhO|&P4q(aYN7|CM-vi4YQlgpG?9bIX-Li;9o?Gfg6Psj79yKurgbKnX_=%z zP=IhuHRRC?gay`*<6@6-MSEO)Reli+_>{a?en{RS-y`1z{7)MHDI?>j@_Ol^nqCVA z9FbSZeWkZE+8`m0F z8%MBU;>?8k`JBonlbJnC)Log~EO%xmSx#hju^i9rWI2|eU^$u|XE~A{W0_BnvK&s2 zupCO|S?)*;v)rBeNBO=asYO=atBQf2E)I+H4e zWRh|DOvdFi`K$BaJ)=qeQq=s_#(MtSKK7k_e4f*Jq-n;IX`*dW-3=L@-QZyio zQijH$(SVB5%=h;v*K^6J7d=%OKv+{muwji%g>z%AxEMYQ#M%pBK4r!Am(k4rE z3@nqVRErv3pyP_-9_jzOIU z(=?*3#28muN`R=`G$z})ae=uadhXYoYmaeHJ6Rt`+w>L0!$YXnpOha(9eqC<^HcIx z`3@NNM)`XA`*K#+DG$jPVIOlbifLXBZj~G4I=Mpjpq}c+e;EH}{Mh(` z@jX=3uNz-BzF_>dan`ucxCb@#1*oB<>>eI>^Ek=lE*^K%n4aKqoX0U9M|m8fF_q_W zn8zU=cksBK$89`r<#CY5Ei{VFJZ=(H!^B4Zuz|+`9!(zmd0fw9ACK#3)YtO3hR4-B zuHtbek1Kdw&f_v3m(r*$;jx#;9v-F8BHS?eLypI89=m8vW_j%7k*SenY9NMxNy^w` z-2Dp_LkIjI8lsP*1^%Esjs3wT^3UWX+M=7}fj7$=ZXHvx)43nX)*GbB2$I=nWgR z^@+Y6uj@}{&|{xGLOYATPVAv4@G+5?n27hZyRNiL6}xVhEVthHNYy^vSg3lAZx5Mu z-wLaiiF>Z)`&QlYT=Vf8=FLNP^H#yDR&BFZv0Ss@xOma3du89MO*_{`p`AXr;dyg! zFdesU`@UDU&5C7KE!SzB_HDE1xplK*HzzS`c33xkyWqJ&-4CIR8M>z5SSUDk(<$0+ z-Kkr2wQ83mX5$9B zJ8Sy^q~`=?$*EKWGYEZBrQBF>y#f|93s!Z?E0!JG9WrOIj6GMYcvzf`XT1ZnFzq>W zO*fSSEESn{P=`9aG_7D2Lnpw}H2I=uy>Qm2i_qN;YE}W>^q>G9aD%E{uVWpk4bvTW z7SF*V@>>j1-rR4uK9~hE!Zt0}s+_<=Y!2ByWI~IuXvd~4z8Aj6XpnJc7heF z;RFF)W1Yw?@G+CYwJQ}nzk3uIl;@BBaQS@H*U1NKv5aoKCfS$hdu2i~aF7_-e;x*o zAFYIeIgN9*A+in*z=F&R$HzyyS@9eY+M*I2;SniUa{ zu-d6(B!bv;uz?>n@oLQh6A9i*fyo4yU2Rn=p6l58?0&qW011d?1;?(Kz{>XP=5?V1 zU)y05%$ju~AjT=2W^D&v0is1a0_?U+zQbHDLrK&DKS|rH;}%2E8#7l_u(?6W^ASSv z3$u>zxvougwa5<4KZ_86H;SP->&zlv^X6sYaM7+nL&6t<=s@7u(wV{=(NGqAg2}U% zQvpS7AHQTxDYh5d72yHpBq&|L%QQ~`;m!aA;La(Yfue+NsUReuHv=iiRvULB1Jq4# zD!`ek(tijRZ-vQqgbk}6koQ~%)8Jq=Aj2v_er$Zt1>bP>*mJCJf*m=0E0b-RKGVIDjO zZ{emD&PApb)WAQt4g)P*w}WAt9!~~&^KyERfDV25h^BJ_JY-&Mo_(Kb)oO@o@+_hn zu?ipfLuP>p7*P0UXT1v6gJ+>+<+>0z@E{QsA%M5eege2gHNSBhuW#NS=-x+K3g#cFL!ySKMcV!Z{OZu3#Q_fUrwJW+OQi8>b-)UZp~z1Sf=k zK6}6oLWIkZc`UMmS38zzAq~$U_@FoG7rTmc6nl`|2Erg`5kHgztzyaLZMWjN^Z=-h1)TR|0djTJ^flIu4Kb|(az2us3omBt zUPyU`f``Hdp^3lnFwml!#O|PgYSD;Pe;$pFSz(C?QMLS{LodT}R4rteV&n|LGRrMe zN(_*fKyZSK9E~jR+tpeHgk#n)-{28eAp4w4;A&I*CXmMzvh5g>5zoUgn#(e2=vED3 z41>yz+v+w#Ln#^%)h|OO49tDze)fMI!5qL$ghObOf6T@mmN@`IXWOWY6befMi?SI& zE^>zflZuY-AdEo^c-4xYZ!~KY*g=+qT;&w#hE<#joQ--(;Z{RS0q!H0djb9cs5Yma z*!j&6Huq&4C*fD(w2D^JcZR*oj#4*31X_PFy=b&~qfZ(Muy^?&gfyadJ78Tk7<<;k#ZneAul|Odi4l$ScfH z^mjyf&rLs}p}aPW1roUhMxgz2>LHAW8M{z08>flUcpCi=f&^{}!b%+;A#X&t*sgDv z9n>@~T7aljf{l1T#;53%O28b^gISuhVd|C=`RpOvoFd*Vs98~^<5Wt@pb8^{kut7F ziPCo4YNQz{y-<0ePDn+LYBfEJ+#gV-$_wO6&Xnyy2B8Za#b?vT`F;Qt?rZA;&mympTCf-#Scu9f(^Rb~4aZuuswjL`h`EYfmCe|NSk?=t zDh_#vAmGN2t)7CJup2ipS?oI3BaPe4ZLg!Gb;-(99jaqNe*W9*m+qRb*K5JWBO?fo z{FF154+|AkU@$j7Wsj6A-jr1tDSCyF6b?ov_KfejX!q#+{d>1We|Rhf8m(3|y74s^ zpwal`<#z35VHLbNj2hK!NeP_8797I$tulDv$}6Z5CcaNqyfVB{_okfYCIRSBrwRNi zYcd>#2#AH4j;k0t+-ZwIta+G(8Vw`}YJwKK2uhP!K{ZXhYfz0&-h9bmvsI@gRy^Ta zRjLS->X1C`Il9=S(&G9vswjfE&MdlVFo0``2koi3TGR~y0w?aeDFUz-Da{N;Yv;^5 zMO1g_t0>j#tWN~keXt_`GoU6$ckUWzpx&}v0I2>W++NQ|1k_kF-rF{KlUI4u;qVlO z<6b3ij`1GuWz-a-8z3?stHD^Gdd%mx*s5EBkHR@bJ~n#jTfi4`8fuas*|Q8xyvH$l znHORiuH%T?DrMq0l6mP-^hbw~HV^vPSE*-qxc0zh(hsqS zb_kZLb{ub8zSa03tpV1cxGv6c_7jv-C^>U+9DyxddBSeF-1>?$0&f{O5oOv zmKa93x#)1uP8TT6R6W0b_Ffy7@28|m)DG&y$h+LBBGzAn)bs~dIYNG=@Mu1dHsCj@ zmu-KV!NIO1;LTEz`e)wQQDETJ3%y}itBuptWvRv$PxHeED51Ajh*}Eqae?w8C-{Xz z#X{n=s;JI^3VBN3$oj-C;KZ#pp-pa%8#Z())W{$nnjWI`fFlYzZy@(m)@T(YI3~hn z@)y+$st{;lX#Yk}H+u#}D4Z@(bF1*iv+BO9Boz;YA#xP{3nrjEV6#Dd;UE7j(5D0a_{+$HZD4b zNDnC;Ij;^+n1>D?KX7Df2HqJmu>w*spR&1uI+Z~FP3~W8!eAO($h_ba9Beh|>?^Dw z_nE&qHPY)Zn;m=5xTCYP)Xl2usA4}T;9#e@U&8($3UQ#~OsWph$aC1Y$LA9zGlFg) zPl*l+pQ}jwi9uGKt65xWeT$AZD7K&`p@7PH!r}r1W>=|+f;W))5E`@xLbi_Kf--2h zxolTM7afGm+=7Ffud*@@dtpGOK$I$5FAibUc8Rs>Or!+|PLkrq<{ z(QavxO(90oKf9nKqsX_gsfo*8$thz~OXk9QXn{Q~HGzd`n8}AJbm&)$RO<>v@lVctv061XD{Qu4n^*Ch>d2;#1=uQVT%tWy~fArfr1xQ zJvv%KcCsQgIK&{*9m%BPl<9IyN!%)UI7tk!9;J+Ua|ROvYK1BJQU68u;bj$wdGjbR zTRc=DVDPp&KBF@uVhAR~uWv`pAWlwm*n2TyoaWXPXNJ5|d=|wJBbgQ*ZW4Kqq0Vcu zJY|~@0ZCN=J77W{PJ!`YCXTp3B&^J*Rm9pRK{5636;WOQ7m4qFij+`cVxaWn&7#G4@i zi2Y4KfFC)IbNDh>|dvZd=$wKUJNoU}f4q;ZZ)J0f~T9Q1EK>P7Pl-EWWY_ zgpN?rUqTfTZ{Z#i0d>#;89?mT;gfzEEHW+X!q*%Pvlj&5`3inPL0mJ8G)*UYBtPoa*v0zSNif!0mFwUX!vjk gxCJPrsPB1%#w7kPcX !empty(array_filter($repData['years'], fn($i) => $i['matched'])), + 'ap' => !empty(array_filter($repData['ap_programs'], fn($i) => $i['matched'])), + 'or' => !empty(array_filter($repData['orientations'], fn($i) => $i['matched'])), + 'fi' => !empty(array_filter($repData['finality_types'], fn($i) => $i['matched'])), + 'kw' => !empty(array_filter($repData['keywords'], fn($i) => $i['matched'])), +]; + // Common HTMX attributes for all active filter buttons $hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-indicator="#rep-indicator"'; ?> @@ -65,7 +77,7 @@ $hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-i