fix repertoire AP/OR/FI columns and main scroll containment

- 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.
This commit is contained in:
Pontoporeia
2026-04-21 19:05:18 +02:00
parent 78449afe64
commit 73fdda4a7f
8 changed files with 38 additions and 32 deletions

View File

@@ -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%);
}

View File

@@ -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;

View File

@@ -6,6 +6,7 @@
.search-main {
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
}

View File

@@ -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]

Binary file not shown.

View File

@@ -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
<?php foreach ($repData['years'] as $item):
$val = (string)$item['value'];
$isActive = in_array($val, $activeSets['years'], true);
$isFaded = $anyActive && !$item['matched'] && !$isActive;
$isFaded = $anyActive && $colHasMatches['years'] && !$item['matched'] && !$isActive;
$cls = 'rep-entry'
. ($isActive ? ' rep-entry--selected' : '')
. ($isFaded ? ' rep-entry--faded' : '');
@@ -89,7 +101,7 @@ $hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-i
<?php foreach ($repData['ap_programs'] as $item):
$val = $item['value'];
$isActive = in_array($val, $activeSets['ap'], true);
$isFaded = $anyActive && !$item['matched'] && !$isActive;
$isFaded = $anyActive && $colHasMatches['ap'] && !$item['matched'] && !$isActive;
$cls = 'rep-entry'
. ($isActive ? ' rep-entry--selected' : '')
. ($isFaded ? ' rep-entry--faded' : '');
@@ -113,7 +125,7 @@ $hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-i
<?php foreach ($repData['orientations'] as $item):
$val = $item['value'];
$isActive = in_array($val, $activeSets['or'], true);
$isFaded = $anyActive && !$item['matched'] && !$isActive;
$isFaded = $anyActive && $colHasMatches['or'] && !$item['matched'] && !$isActive;
$cls = 'rep-entry'
. ($isActive ? ' rep-entry--selected' : '')
. ($isFaded ? ' rep-entry--faded' : '');
@@ -137,7 +149,7 @@ $hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-i
<?php foreach ($repData['finality_types'] as $item):
$val = $item['value'];
$isActive = in_array($val, $activeSets['fi'], true);
$isFaded = $anyActive && !$item['matched'] && !$isActive;
$isFaded = $anyActive && $colHasMatches['fi'] && !$item['matched'] && !$isActive;
$cls = 'rep-entry'
. ($isActive ? ' rep-entry--selected' : '')
. ($isFaded ? ' rep-entry--faded' : '');
@@ -179,7 +191,7 @@ $hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-i
<?php foreach ($repData['keywords'] as $item):
$val = $item['value'];
$isActive = in_array($val, $activeSets['kw'], true);
$isFaded = $anyActive && !$item['matched'] && !$isActive;
$isFaded = $anyActive && $colHasMatches['kw'] && !$item['matched'] && !$isActive;
$cls = 'rep-entry'
. ($isActive ? ' rep-entry--selected' : '')
. ($isFaded ? ' rep-entry--faded' : '');