fix: preload historik per spelare så history-chart renderas direkt #10

Closed
opened 2026-05-21 15:43:28 +02:00 by shcizo · 0 comments
Owner

Beskrivning

History-charten i den expanderade spelarraden renderas inte vid första expansionen — den dyker först upp vid andra (eller senare) klick på samma rad. Pattern är att de tomma <div class="player-chart">-elementen finns i DOM:en efter HTMX-swappet, men chart.js-initialiseringen hinner antingen inte köra, eller väljer fel container, på första swappen.

Konkret bug-flöde idag:

  1. Användaren klickar på en rad → togglePlayerHistory(pdgaNumber) i public/js/players.js visar .expanded-content-raden.
  2. Vid första klick: HTMX hämtar /partials/player-history/:pdgaNumber och swappar in markupen i #history-content-{pdgaNumber}.
  3. setupTooltipsAfterSwap (kopplad mot htmx:afterSwap) försöker hitta .player-chart / .chart-container i swappad markup och anropa createRatingChart().
  4. Vid första klick: charten renderas inte. Vid andra klick: den finns.

Förväntat beteende

History-charten ska finnas i DOM:en (men dold) redan vid sidladdning. När användaren expanderar raden ska charten synas omedelbart utan HTMX-runda och utan race-condition.

Föreslagen lösning: preload server-side, droppa HTMX lazy-load

Istället för att försöka fixa race-conditionen mellan HTMX-swap och chart-init, rendera player-history-partialen inline för varje rad direkt i views/partials/ratings-table.ejs. Hela .expanded-content-raden blir då fullt populerad vid första render, dold med display: none tills användaren expanderar.

Det betyder:

  • Inga HTMX-fetches per rad — alla data redan på första svaret från /partials/ratings-table.
  • chart.js kan initialiseras vid första setupTooltipsAfterSwap-anrop (samma som körs när tabellen laddas), och hitta alla .player-chart-element samtidigt.
  • Lösning på den bredare buggen att första-klick aldrig får sina charts.

Tekniska noteringar

Datakontrakt-ändring: chart.js förväntar sig en history-array av { rating, date }-objekt. Idag exponerar getAllRatingsFromDB (src/services/player-service.js) bara monthlyHistory: number[] per spelare (introducerades i #6 för sparklinerna). Två alternativ:

  • (a) Lägg till ratingHistory: { rating, date }[] på player-objektet — bulkhämta i samma stil som getAllMonthlyHistoriesFromDB (en query, gruppera i minnet). Mer data per request men hela serien finns redan i rating_history-tabellen.
  • (b) Anpassa chart.js att rendera utan datum — förlora "MMM YY"-x-labels men slipper extra fält. Sämre design-fidelity.

(a) är att föredra — minimerar designavvikelser och datavolymen är trivial (~11 spelare × N månader).

Filer som troligen påverkas:

  • src/services/player-service.js — exponera ratingHistory i bulkpathen
  • src/models/player.js — eventuellt en getAllRatingHistoriesFromDB helper
  • src/routes/players.js/partials/ratings-table-routen passerar full history per spelare
  • views/partials/ratings-table.ejs — inkludera player-history partialen inline per rad, ta bort loading-chart-placeholdern
  • public/js/players.jstogglePlayerHistory slutar trigga HTMX-fetch (den är redan idempotent men koden kan förenklas)
  • src/routes/players.js/partials/player-history/:pdgaNumber-endpointen blir oanvänd. Antingen ta bort eller behåll för bakåtkompatibilitet.

Steg för att reproducera

  1. Öppna / i webbläsaren efter dco restart (ren cache).
  2. Klicka på en valfri spelarrad.
  3. Förväntat: history-chart till höger om detail-grid.
  4. Faktiskt: tom yta där charten ska vara. Detail-grid till vänster syns korrekt.
  5. Klicka för att stänga raden, klicka igen för att öppna.
  6. Nu syns charten.

Scope

Inkluderat: Preload av rating history server-side, refaktor av charts init så att första-klick alltid funkar, datakontrakts-uppdatering för ratingHistory-fältet.

Exkluderat: Sparkline-rendering (redan server-side, fungerar). Topbar-refresh-logik. Övriga sidor (/courses).

Beroenden

Bygger på #4 (shared visual layer) och #7 (expanderad rad). Lösning sammanfaller med arbetet på feat/shared-visual-layer-topbar-4-grenen, men hör hemma som separat issue/PR eftersom den fixar en regressions-bug snarare än levererar ny funktionalitet.

## Beskrivning History-charten i den expanderade spelarraden renderas inte vid första expansionen — den dyker först upp vid andra (eller senare) klick på samma rad. Pattern är att de tomma `<div class="player-chart">`-elementen finns i DOM:en efter HTMX-swappet, men `chart.js`-initialiseringen hinner antingen inte köra, eller väljer fel container, på första swappen. Konkret bug-flöde idag: 1. Användaren klickar på en rad → `togglePlayerHistory(pdgaNumber)` i `public/js/players.js` visar `.expanded-content`-raden. 2. Vid första klick: HTMX hämtar `/partials/player-history/:pdgaNumber` och swappar in markupen i `#history-content-{pdgaNumber}`. 3. `setupTooltipsAfterSwap` (kopplad mot `htmx:afterSwap`) försöker hitta `.player-chart` / `.chart-container` i swappad markup och anropa `createRatingChart()`. 4. Vid första klick: charten renderas inte. Vid andra klick: den finns. ## Förväntat beteende History-charten ska finnas i DOM:en (men dold) redan vid sidladdning. När användaren expanderar raden ska charten synas omedelbart utan HTMX-runda och utan race-condition. ## Föreslagen lösning: preload server-side, droppa HTMX lazy-load Istället för att försöka fixa race-conditionen mellan HTMX-swap och chart-init, rendera `player-history`-partialen inline för varje rad direkt i `views/partials/ratings-table.ejs`. Hela `.expanded-content`-raden blir då fullt populerad vid första render, dold med `display: none` tills användaren expanderar. Det betyder: - Inga HTMX-fetches per rad — alla data redan på första svaret från `/partials/ratings-table`. - `chart.js` kan initialiseras vid första `setupTooltipsAfterSwap`-anrop (samma som körs när tabellen laddas), och hitta alla `.player-chart`-element samtidigt. - Lösning på den bredare buggen att första-klick aldrig får sina charts. ## Tekniska noteringar **Datakontrakt-ändring**: chart.js förväntar sig en `history`-array av `{ rating, date }`-objekt. Idag exponerar `getAllRatingsFromDB` (`src/services/player-service.js`) bara `monthlyHistory: number[]` per spelare (introducerades i #6 för sparklinerna). Två alternativ: - **(a) Lägg till `ratingHistory: { rating, date }[]` på player-objektet** — bulkhämta i samma stil som `getAllMonthlyHistoriesFromDB` (en query, gruppera i minnet). Mer data per request men hela serien finns redan i `rating_history`-tabellen. - **(b) Anpassa chart.js att rendera utan datum** — förlora "MMM YY"-x-labels men slipper extra fält. Sämre design-fidelity. (a) är att föredra — minimerar designavvikelser och datavolymen är trivial (~11 spelare × N månader). **Filer som troligen påverkas:** - `src/services/player-service.js` — exponera `ratingHistory` i bulkpathen - `src/models/player.js` — eventuellt en `getAllRatingHistoriesFromDB` helper - `src/routes/players.js` — `/partials/ratings-table`-routen passerar full history per spelare - `views/partials/ratings-table.ejs` — inkludera `player-history` partialen inline per rad, ta bort `loading-chart`-placeholdern - `public/js/players.js` — `togglePlayerHistory` slutar trigga HTMX-fetch (den är redan idempotent men koden kan förenklas) - `src/routes/players.js` — `/partials/player-history/:pdgaNumber`-endpointen blir oanvänd. Antingen ta bort eller behåll för bakåtkompatibilitet. ## Steg för att reproducera 1. Öppna `/` i webbläsaren efter `dco restart` (ren cache). 2. Klicka på en valfri spelarrad. 3. Förväntat: history-chart till höger om detail-grid. 4. Faktiskt: tom yta där charten ska vara. Detail-grid till vänster syns korrekt. 5. Klicka för att stänga raden, klicka igen för att öppna. 6. Nu syns charten. ## Scope **Inkluderat:** Preload av rating history server-side, refaktor av charts init så att första-klick alltid funkar, datakontrakts-uppdatering för `ratingHistory`-fältet. **Exkluderat:** Sparkline-rendering (redan server-side, fungerar). Topbar-refresh-logik. Övriga sidor (`/courses`). ## Beroenden Bygger på #4 (shared visual layer) och #7 (expanderad rad). Lösning sammanfaller med arbetet på `feat/shared-visual-layer-topbar-4`-grenen, men hör hemma som separat issue/PR eftersom den fixar en regressions-bug snarare än levererar ny funktionalitet.
shcizo added the bugenhancement labels 2026-05-21 15:43:28 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: shcizo/pdga-rating#10