mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 11:39:18 +02:00
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:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,16 +1,13 @@
|
|||||||
# Admin credentials (contains bcrypt hash — never commit)
|
|
||||||
config/admin_credentials.php
|
|
||||||
|
|
||||||
# Vendor directory (third-party code)
|
# Vendor directory (third-party code)
|
||||||
vendor/
|
vendor/
|
||||||
compose.lock
|
compose.lock
|
||||||
|
|
||||||
### Test databases ###
|
### Test databases ###
|
||||||
storage/test.db
|
app/storage/test.db
|
||||||
|
|
||||||
### Logs ###
|
### Logs ###
|
||||||
error.log
|
error.log
|
||||||
storage/cache/
|
app/storage/cache/
|
||||||
|
|
||||||
# Nix
|
# Nix
|
||||||
.direnv/
|
.direnv/
|
||||||
|
|||||||
16
TODO.md
16
TODO.md
@@ -1,7 +1,13 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
## Fix repertoire.php
|
## Répertoire page fixes
|
||||||
- [ ] Fix AP and orientation columns not working like other columns
|
- [x] Fix AP and orientation columns returning empty results when clicked
|
||||||
- [ ] Make main element scrollable instead of body
|
- [x] Fix multi-select being blocked (only one entry selectable at a time)
|
||||||
- [ ] Update public.css (general)
|
- [x] Fix all other columns becoming faded when AP/OR filter is selected
|
||||||
- [ ] Update repertoire.css (page-specific)
|
- [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
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -22,13 +23,8 @@ body {
|
|||||||
rgba(0, 0, 0, 0) 92%,
|
rgba(0, 0, 0, 0) 92%,
|
||||||
rgba(149, 87, 181, 1) 100%
|
rgba(149, 87, 181, 1) 100%
|
||||||
);
|
);
|
||||||
}
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -132,7 +128,8 @@ body > header nav ul a[aria-current="page"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
overflow: scroll;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
@@ -140,8 +137,8 @@ main {
|
|||||||
============================================================ */
|
============================================================ */
|
||||||
.header-search-wrap {
|
.header-search-wrap {
|
||||||
padding: 0 0;
|
padding: 0 0;
|
||||||
|
flex-shrink: 0;
|
||||||
background-color: var(--gradient-4);
|
background-color: var(--gradient-4);
|
||||||
|
|
||||||
background: linear-gradient(180deg, var(--gradient-4) 0%, #ffffffee 100%);
|
background: linear-gradient(180deg, var(--gradient-4) 0%, #ffffffee 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,10 @@
|
|||||||
|
|
||||||
@import url("./variables.css");
|
@import url("./variables.css");
|
||||||
|
|
||||||
main {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cards grid — scrollable main area */
|
/* Cards grid — scrollable main area */
|
||||||
.home-main {
|
.home-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
.search-main {
|
.search-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
@@ -53,6 +53,18 @@ $anyActive = !empty($activeSets['years']) || !empty($activeSets['ap'])
|
|||||||
|| !empty($activeSets['or']) || !empty($activeSets['fi'])
|
|| !empty($activeSets['or']) || !empty($activeSets['fi'])
|
||||||
|| !empty($activeSets['kw']);
|
|| !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
|
// Common HTMX attributes for all active filter buttons
|
||||||
$hx = 'hx-target="#repertoire-index" hx-swap="outerHTML" hx-push-url="true" hx-indicator="#rep-indicator"';
|
$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):
|
<?php foreach ($repData['years'] as $item):
|
||||||
$val = (string)$item['value'];
|
$val = (string)$item['value'];
|
||||||
$isActive = in_array($val, $activeSets['years'], true);
|
$isActive = in_array($val, $activeSets['years'], true);
|
||||||
$isFaded = $anyActive && !$item['matched'] && !$isActive;
|
$isFaded = $anyActive && $colHasMatches['years'] && !$item['matched'] && !$isActive;
|
||||||
$cls = 'rep-entry'
|
$cls = 'rep-entry'
|
||||||
. ($isActive ? ' rep-entry--selected' : '')
|
. ($isActive ? ' rep-entry--selected' : '')
|
||||||
. ($isFaded ? ' rep-entry--faded' : '');
|
. ($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):
|
<?php foreach ($repData['ap_programs'] as $item):
|
||||||
$val = $item['value'];
|
$val = $item['value'];
|
||||||
$isActive = in_array($val, $activeSets['ap'], true);
|
$isActive = in_array($val, $activeSets['ap'], true);
|
||||||
$isFaded = $anyActive && !$item['matched'] && !$isActive;
|
$isFaded = $anyActive && $colHasMatches['ap'] && !$item['matched'] && !$isActive;
|
||||||
$cls = 'rep-entry'
|
$cls = 'rep-entry'
|
||||||
. ($isActive ? ' rep-entry--selected' : '')
|
. ($isActive ? ' rep-entry--selected' : '')
|
||||||
. ($isFaded ? ' rep-entry--faded' : '');
|
. ($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):
|
<?php foreach ($repData['orientations'] as $item):
|
||||||
$val = $item['value'];
|
$val = $item['value'];
|
||||||
$isActive = in_array($val, $activeSets['or'], true);
|
$isActive = in_array($val, $activeSets['or'], true);
|
||||||
$isFaded = $anyActive && !$item['matched'] && !$isActive;
|
$isFaded = $anyActive && $colHasMatches['or'] && !$item['matched'] && !$isActive;
|
||||||
$cls = 'rep-entry'
|
$cls = 'rep-entry'
|
||||||
. ($isActive ? ' rep-entry--selected' : '')
|
. ($isActive ? ' rep-entry--selected' : '')
|
||||||
. ($isFaded ? ' rep-entry--faded' : '');
|
. ($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):
|
<?php foreach ($repData['finality_types'] as $item):
|
||||||
$val = $item['value'];
|
$val = $item['value'];
|
||||||
$isActive = in_array($val, $activeSets['fi'], true);
|
$isActive = in_array($val, $activeSets['fi'], true);
|
||||||
$isFaded = $anyActive && !$item['matched'] && !$isActive;
|
$isFaded = $anyActive && $colHasMatches['fi'] && !$item['matched'] && !$isActive;
|
||||||
$cls = 'rep-entry'
|
$cls = 'rep-entry'
|
||||||
. ($isActive ? ' rep-entry--selected' : '')
|
. ($isActive ? ' rep-entry--selected' : '')
|
||||||
. ($isFaded ? ' rep-entry--faded' : '');
|
. ($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):
|
<?php foreach ($repData['keywords'] as $item):
|
||||||
$val = $item['value'];
|
$val = $item['value'];
|
||||||
$isActive = in_array($val, $activeSets['kw'], true);
|
$isActive = in_array($val, $activeSets['kw'], true);
|
||||||
$isFaded = $anyActive && !$item['matched'] && !$isActive;
|
$isFaded = $anyActive && $colHasMatches['kw'] && !$item['matched'] && !$isActive;
|
||||||
$cls = 'rep-entry'
|
$cls = 'rep-entry'
|
||||||
. ($isActive ? ' rep-entry--selected' : '')
|
. ($isActive ? ' rep-entry--selected' : '')
|
||||||
. ($isFaded ? ' rep-entry--faded' : '');
|
. ($isFaded ? ' rep-entry--faded' : '');
|
||||||
|
|||||||
Reference in New Issue
Block a user