Add "Aller à" year-jump shortcut next to the filters

Distinct from the existing "Année" filter (which restricts the view
to just that year): this re-centers the sliding window on 1 January
of the chosen year and scrolls there, while staying in the continuous
view -- scrolling still extends the window normally in both
directions, so overlaps between years stay visible, matching the
earlier stated preference for a continuous view over a filtered one.

Resets to the placeholder immediately after firing since it's a
one-shot action, not a sticky filter. Guards against racing the
"Année" watcher's own exitYearMode() when a year filter is already
active when the jump is triggered.
This commit is contained in:
2026-09-04 21:33:59 +02:00
parent 5afc5905d7
commit 53c4e58e72
2 changed files with 51 additions and 0 deletions
@@ -197,6 +197,7 @@
filterClient: '', filterClient: '',
filterType: '', filterType: '',
filterYear: '', filterYear: '',
jumpYearValue: '',
groupBy: 'month', groupBy: 'month',
onlyErrors: false, onlyErrors: false,
hoverCol: null, hoverCol: null,
@@ -649,9 +650,52 @@
if (wrap) wrap.scrollTop = wrap.scrollHeight; if (wrap) wrap.scrollTop = wrap.scrollHeight;
this.detectCurrentYear(); this.detectCurrentYear();
}, },
// "Aller à" -- a one-shot navigation shortcut, distinct from the
// "Année" filter: it re-centers the sliding window on 1 January of
// the chosen year and scrolls there, but (unlike filterYear) doesn't
// restrict the view to just that year -- scrolling up/down still
// extends the window normally, so you can still see the overlap
// with neighbouring years.
onJumpYearChange() {
const year = this.jumpYearValue;
this.jumpYearValue = ''; // reset immediately -- this is an action, not a sticky filter
this.jumpToYear(year);
},
async jumpToYear(year) {
if (!year) return;
// A year filter would otherwise fight with the window this sets
// below -- clear it first, silencing the watcher's own
// exitYearMode() so its (different) window doesn't race this one.
if (this.filterYear) {
this._skipYearWatch = true;
this.filterYear = '';
}
this.loading = true;
this.error = null;
try {
const yearStart = year + '-01-01';
this.windowStart = yearStart;
this.windowEnd = addMonths(yearStart, WINDOW_MONTHS * 2);
const { data, includedMap } = await fetchLignes(rangeUrl(this.windowStart, this.windowEnd));
this.rows = buildRows(data, includedMap);
} catch (err) {
this.error = err.message;
} finally {
this.loading = false;
}
await this.$nextTick();
const wrap = this.$refs.tableWrap;
if (wrap) wrap.scrollTop = 0;
this.detectCurrentYear();
this.checkEdges();
},
}, },
watch: { watch: {
filterYear(newYear, oldYear) { filterYear(newYear, oldYear) {
if (this._skipYearWatch) {
this._skipYearWatch = false;
return;
}
if (newYear) { if (newYear) {
this.enterYearMode(newYear); this.enterYearMode(newYear);
} else if (oldYear) { } else if (oldYear) {
@@ -43,6 +43,13 @@
</select> </select>
</label> </label>
<label>Aller à
<select v-model="jumpYearValue" @change="onJumpYearChange">
<option value="">Aller à…</option>
<option v-for="y in allYearsList" :key="y" :value="y">{{ y }}</option>
</select>
</label>
<label>Regrouper par <label>Regrouper par
<select v-model="groupBy"> <select v-model="groupBy">
<option value="none">Aucun</option> <option value="none">Aucun</option>