From 61aa1decee13df8aa1e643cc746331437e5cbda7 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Thu, 2 Jul 2026 07:42:19 -0400 Subject: [PATCH 1/4] bug: remove limits for filters --- components/player/PlayerIntroDashboard.vue | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/components/player/PlayerIntroDashboard.vue b/components/player/PlayerIntroDashboard.vue index 3218ed54..212935f8 100644 --- a/components/player/PlayerIntroDashboard.vue +++ b/components/player/PlayerIntroDashboard.vue @@ -54,10 +54,18 @@ const props = defineProps<{ source?: string | null; limit?: number | null; since?: string | null; + until?: string | null; }>(); const { t, te } = useI18n(); +// A null/absent limit means "no match cap" (a date-range / season filter is +// driving the window); only fall back to the recent-30 view when there is no +// range at all. Bounded so an all-time query can't be unbounded. +const effectiveLimit = computed(() => + props.limit != null ? props.limit : props.since ? 1000 : 30, +); + function statTitle(key: string): string { return te(`stat_glossary.${key}.label`) ? t(`stat_glossary.${key}.label`) @@ -92,8 +100,11 @@ function buildMatchesWhere() { }, }; } - if (props.since) { - where.started_at = { _gte: props.since }; + if (props.since || props.until) { + where.started_at = { + ...(props.since ? { _gte: props.since } : {}), + ...(props.until ? { _lte: props.until } : {}), + }; } return where; } @@ -185,7 +196,7 @@ async function load() { variables: { steamId: props.steamId, matchesWhere: buildMatchesWhere(), - limit: props.limit ?? 30, + limit: effectiveLimit.value, statsLimit: 200, hltvLimit: 600, }, @@ -465,7 +476,7 @@ const { (steamId) => ({ steamId, matchesWhere: buildMatchesWhere(), - limit: props.limit ?? 30, + limit: effectiveLimit.value, statsLimit: 200, hltvLimit: 600, }), From 8d23479280cdb0e377111e99738ce35d3ab5b0d0 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Thu, 2 Jul 2026 08:25:31 -0400 Subject: [PATCH 2/4] wip --- components/player/PlayerIntroDashboard.vue | 3 ++- i18n/locales/en.json | 2 +- pages/players/[id].vue | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/player/PlayerIntroDashboard.vue b/components/player/PlayerIntroDashboard.vue index 212935f8..302c8bba 100644 --- a/components/player/PlayerIntroDashboard.vue +++ b/components/player/PlayerIntroDashboard.vue @@ -229,6 +229,7 @@ watch( props.matchType, props.limit, props.since, + props.until, ], load, { immediate: true }, @@ -485,7 +486,7 @@ const { rawStats: (data?.playerIntroStats ?? []) as RawStats[], hltvRows: (data?.playerIntroHltv ?? []) as any[], }), - () => [props.source, props.matchType, props.limit, props.since], + () => [props.source, props.matchType, props.limit, props.since, props.until], ); const comparePoints = computed(() => { diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 3bc5423f..9b63f7b7 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -1604,7 +1604,7 @@ "refresh_dialog_title": "Reindex the search index?", "refresh_dialog_description": "This will re-sync every player into the Typesense search index in batches. It runs in the background and you can watch its progress here.", "recompute_elo_title": "Recompute Player ELO", - "recompute_elo_description": "Wipe and rebuild every player's ELO by replaying all finished matches in order, in batches. Use this after an ELO formula change or if ratings look wrong. Search results update automatically as ELO is recalculated.", + "recompute_elo_description": "Wipe and rebuild every player's ELO by replaying all finished matches in order, in batches. When seasons are enabled this also rebuilds each season's ELO from the matches that fall within it. Use this after an ELO formula change or if ratings look wrong. Search results update automatically as ELO is recalculated.", "recompute_elo_button": "Recompute ELO", "recomputing_elo": "Recomputing...", "recompute_elo_queued": "ELO recompute started", diff --git a/pages/players/[id].vue b/pages/players/[id].vue index a089aa3c..ab0b235f 100644 --- a/pages/players/[id].vue +++ b/pages/players/[id].vue @@ -2603,6 +2603,7 @@ const playerHeroTeamChipDotClasses = :source="effectiveSource" :limit="statsMatchLimit" :since="sinceTimestamp" + :until="untilTimestamp" /> From eb7e2821c5b5cc084fc2aa834223a417ba0c7b9c Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Thu, 2 Jul 2026 08:56:03 -0400 Subject: [PATCH 3/4] wip --- components/seasons/SeasonRebuildProgress.vue | 60 +++++++++ i18n/locales/en.json | 3 + layouts/components/LeftNav.vue | 25 +++- pages/seasons/index.vue | 125 +++++++++++++------ 4 files changed, 173 insertions(+), 40 deletions(-) create mode 100644 components/seasons/SeasonRebuildProgress.vue diff --git a/components/seasons/SeasonRebuildProgress.vue b/components/seasons/SeasonRebuildProgress.vue new file mode 100644 index 00000000..8472482e --- /dev/null +++ b/components/seasons/SeasonRebuildProgress.vue @@ -0,0 +1,60 @@ + + + diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 9b63f7b7..a59913e9 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -2203,6 +2203,9 @@ "upcoming_title": "Upcoming Seasons", "past_title": "Past Seasons", "rebuild": "Rebuild", + "rebuild_elo": "Rebuild ELO", + "rebuild_required": "Rebuild Required", + "needs_rebuild_notice": "This season's ELO is out of date and its standings are incorrect. Rebuild to recompute ELO and stats from its matches.", "delete": "Delete", "deleted": "Season deleted", "delete_confirm_title": "Delete this season?", diff --git a/layouts/components/LeftNav.vue b/layouts/components/LeftNav.vue index 67728c31..b335d27e 100644 --- a/layouts/components/LeftNav.vue +++ b/layouts/components/LeftNav.vue @@ -704,7 +704,7 @@ function onLeftNavTouchEnd(e: TouchEvent) { {{ $t("layouts.app_nav.administration.seasons") }} + @@ -969,7 +973,7 @@ function onLeftNavTouchEnd(e: TouchEvent) { - -
-
- - - {{ $t("pages.seasons.backfill_running") }} - - -
-
-
-
-
- {{ backfill.status.value?.completed || 0 }} / - {{ backfill.status.value?.total || 0 }} - {{ $t("pages.seasons.matches_label") }} -
-
-
{{ $t("pages.seasons.active") }} + + + {{ $t("pages.seasons.rebuild_required") }} + + +
+ + + {{ $t("pages.seasons.needs_rebuild_notice") }} + + +
+
+

+ +

@@ -480,8 +495,9 @@ const dangerBtn = [
+
@@ -515,6 +531,13 @@ const dangerBtn = [ : $t("pages.seasons.ended") }} + + + {{ $t("pages.seasons.rebuild_required") }} +

+ + +
+ + @@ -613,6 +660,7 @@ type Season = { starts_at: string; ends_at: string | null; created_at: string; + needs_rebuild: boolean; }; export default { @@ -631,6 +679,7 @@ export default { starts_at: true, ends_at: true, created_at: true, + needs_rebuild: true, }, ], }), From d04ec0c576aeac9343910364fea1e4d65c869709 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Thu, 2 Jul 2026 09:10:26 -0400 Subject: [PATCH 4/4] wip --- components/hub/NotificationsPanel.vue | 4 ++ layouts/components/AppNotifications.vue | 6 ++ layouts/components/LeftNav.vue | 22 ++----- stores/NotificationStore.ts | 84 +++++++++++++++++++++++-- 4 files changed, 94 insertions(+), 22 deletions(-) diff --git a/components/hub/NotificationsPanel.vue b/components/hub/NotificationsPanel.vue index bc493520..2e7c4cb5 100644 --- a/components/hub/NotificationsPanel.vue +++ b/components/hub/NotificationsPanel.vue @@ -178,6 +178,10 @@ export default { }); } } + // Synthetic notifications have no backing row to delete. + if (notification.__synthetic) { + return; + } await this.deleteNotification(notification.id); }, async dismissNotification(id: string) { diff --git a/layouts/components/AppNotifications.vue b/layouts/components/AppNotifications.vue index 01f71af1..0b461e47 100644 --- a/layouts/components/AppNotifications.vue +++ b/layouts/components/AppNotifications.vue @@ -158,6 +158,12 @@ export default { } } + // Synthetic notifications have no backing row — they clear on their own + // when the underlying state changes (e.g. seasons.needs_rebuild flips). + if (notification.__synthetic) { + return; + } + await this.deleteNotification(notification.id); }, async dismissNotification(id: string) { diff --git a/layouts/components/LeftNav.vue b/layouts/components/LeftNav.vue index b335d27e..cb954770 100644 --- a/layouts/components/LeftNav.vue +++ b/layouts/components/LeftNav.vue @@ -973,7 +973,7 @@ function onLeftNavTouchEnd(e: TouchEvent) {