fix(series): sticky tabs + controls on the Series view
The Series tab strip and the Browse search/sort (and Suggestions controls) scrolled away on a long grid (operator-asked). Hoist the tabs + active-tab controls into one sticky header pinned under the 64px TopNav. The controls had to leave v-window — it clips sticky children — so they're driven by the tab from the header instead of living inside each window-item. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,35 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container fluid class="pt-2 pb-6">
|
<v-container fluid class="pt-2 pb-6">
|
||||||
<v-tabs v-model="tab" density="compact" class="mb-3">
|
<!-- Tabs + the active tab's controls live in one sticky block pinned under
|
||||||
<v-tab value="browse">Browse</v-tab>
|
the 64px TopNav (operator-asked 2026-06-12), so the axis switcher and
|
||||||
<v-tab value="suggestions">
|
search/sort stay reachable on a long grid. The controls can't sit
|
||||||
Suggestions
|
inside v-window (it clips sticky children), so they're hoisted here. -->
|
||||||
<v-badge
|
<div class="fc-series__head">
|
||||||
v-if="sug.suggestions.length" :content="sug.suggestions.length"
|
<v-tabs v-model="tab" density="compact">
|
||||||
inline color="accent"
|
<v-tab value="browse">Browse</v-tab>
|
||||||
|
<v-tab value="suggestions">
|
||||||
|
Suggestions
|
||||||
|
<v-badge
|
||||||
|
v-if="sug.suggestions.length" :content="sug.suggestions.length"
|
||||||
|
inline color="accent"
|
||||||
|
/>
|
||||||
|
</v-tab>
|
||||||
|
</v-tabs>
|
||||||
|
|
||||||
|
<div v-if="tab === 'browse'" class="fc-series-browse__controls">
|
||||||
|
<v-text-field
|
||||||
|
v-model="query"
|
||||||
|
density="compact" variant="outlined" hide-details clearable
|
||||||
|
label="Search series" prepend-inner-icon="mdi-magnify"
|
||||||
|
style="max-width: 320px;"
|
||||||
/>
|
/>
|
||||||
</v-tab>
|
<v-select
|
||||||
</v-tabs>
|
:model-value="store.sort"
|
||||||
|
:items="sortItems"
|
||||||
|
density="compact" variant="outlined" hide-details
|
||||||
|
label="Sort" style="max-width: 220px;"
|
||||||
|
@update:model-value="store.setSort($event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="fc-sug__controls">
|
||||||
|
<v-switch
|
||||||
|
:model-value="sug.enabled" color="accent" density="compact"
|
||||||
|
hide-details label="Matching on"
|
||||||
|
@update:model-value="sug.setEnabled($event)"
|
||||||
|
/>
|
||||||
|
<v-text-field
|
||||||
|
:model-value="sug.threshold"
|
||||||
|
type="number" min="0" max="1" step="0.05"
|
||||||
|
density="compact" variant="outlined" hide-details
|
||||||
|
label="Threshold" style="max-width: 130px;"
|
||||||
|
@change="sug.setThreshold(Number($event.target.value))"
|
||||||
|
/>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
variant="tonal" prepend-icon="mdi-radar" @click="sug.rescan()"
|
||||||
|
>Rescan</v-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<v-window v-model="tab">
|
<v-window v-model="tab">
|
||||||
<!-- ---- Browse ---- -->
|
<!-- ---- Browse ---- -->
|
||||||
<v-window-item value="browse">
|
<v-window-item value="browse">
|
||||||
<div class="fc-series-browse__controls">
|
|
||||||
<v-text-field
|
|
||||||
v-model="query"
|
|
||||||
density="compact" variant="outlined" hide-details clearable
|
|
||||||
label="Search series" prepend-inner-icon="mdi-magnify"
|
|
||||||
style="max-width: 320px;"
|
|
||||||
/>
|
|
||||||
<v-select
|
|
||||||
:model-value="store.sort"
|
|
||||||
:items="sortItems"
|
|
||||||
density="compact" variant="outlined" hide-details
|
|
||||||
label="Sort" style="max-width: 220px;"
|
|
||||||
@update:model-value="store.setSort($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-alert v-if="store.error" type="error" variant="tonal" closable class="my-4">
|
<v-alert v-if="store.error" type="error" variant="tonal" closable class="my-4">
|
||||||
Failed to load: {{ store.error }}
|
Failed to load: {{ store.error }}
|
||||||
</v-alert>
|
</v-alert>
|
||||||
@@ -138,25 +163,6 @@
|
|||||||
|
|
||||||
<!-- ---- Suggestions ---- -->
|
<!-- ---- Suggestions ---- -->
|
||||||
<v-window-item value="suggestions">
|
<v-window-item value="suggestions">
|
||||||
<div class="fc-sug__controls">
|
|
||||||
<v-switch
|
|
||||||
:model-value="sug.enabled" color="accent" density="compact"
|
|
||||||
hide-details label="Matching on"
|
|
||||||
@update:model-value="sug.setEnabled($event)"
|
|
||||||
/>
|
|
||||||
<v-text-field
|
|
||||||
:model-value="sug.threshold"
|
|
||||||
type="number" min="0" max="1" step="0.05"
|
|
||||||
density="compact" variant="outlined" hide-details
|
|
||||||
label="Threshold" style="max-width: 130px;"
|
|
||||||
@change="sug.setThreshold(Number($event.target.value))"
|
|
||||||
/>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn
|
|
||||||
variant="tonal" prepend-icon="mdi-radar" @click="sug.rescan()"
|
|
||||||
>Rescan</v-btn>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-alert v-if="sug.error" type="error" variant="tonal" closable class="my-4">
|
<v-alert v-if="sug.error" type="error" variant="tonal" closable class="my-4">
|
||||||
{{ sug.error }}
|
{{ sug.error }}
|
||||||
</v-alert>
|
</v-alert>
|
||||||
@@ -287,8 +293,17 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* Sticky header (tabs + active-tab controls) pinned under the 64px TopNav, so
|
||||||
|
content scrolls cleanly beneath it. Surface bg matches SettingsView. */
|
||||||
|
.fc-series__head {
|
||||||
|
position: sticky;
|
||||||
|
top: 64px;
|
||||||
|
z-index: 4;
|
||||||
|
background: rgb(var(--v-theme-surface));
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
.fc-series-browse__controls {
|
.fc-series-browse__controls {
|
||||||
display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 16px;
|
display: flex; flex-wrap: wrap; gap: 12px; padding-top: 12px;
|
||||||
}
|
}
|
||||||
.fc-series-browse__empty {
|
.fc-series-browse__empty {
|
||||||
padding: 48px; text-align: center;
|
padding: 48px; text-align: center;
|
||||||
@@ -351,7 +366,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
/* Suggestions tab */
|
/* Suggestions tab */
|
||||||
.fc-sug__controls {
|
.fc-sug__controls {
|
||||||
display: flex; align-items: center; gap: 16px; margin-bottom: 12px;
|
display: flex; align-items: center; gap: 16px; padding-top: 12px;
|
||||||
}
|
}
|
||||||
.fc-sug__list { display: flex; flex-direction: column; gap: 8px; }
|
.fc-sug__list { display: flex; flex-direction: column; gap: 8px; }
|
||||||
.fc-sug__row {
|
.fc-sug__row {
|
||||||
|
|||||||
Reference in New Issue
Block a user