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 01fe6ed..6e84cee 100644 Binary files a/app/storage/test.db and b/app/storage/test.db differ diff --git a/app/templates/partials/repertoire-index.php b/app/templates/partials/repertoire-index.php index 8c0bf79..ff070e1 100644 --- a/app/templates/partials/repertoire-index.php +++ b/app/templates/partials/repertoire-index.php @@ -53,6 +53,18 @@ $anyActive = !empty($activeSets['years']) || !empty($activeSets['ap']) || !empty($activeSets['or']) || !empty($activeSets['fi']) || !empty($activeSets['kw']); +// Per-column: does this dimension have ANY matched entry in the current result set? +// When a column has zero matched entries despite other filters being active, it means +// no thesis in the matched set carries that FK — the column has no useful cross-filter +// signal and its entries must NOT be faded (the user may still want to select them). +$colHasMatches = [ + 'years' => !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