Update in-app Guide for this session's features, extend passing purge to Clear data
The in-app Guide page hadn't been updated for the guided practice exercises, their mobile self-service controls, the end-of-practice summary, or the new Resultatarkiv view - none of it was documented anywhere a user would find it. Added three new Training walkthrough steps and a new Resultatarkiv section (overview card + 5-step guide). While correcting guide text that claimed raw SQLite passing rows are always retained, found the same gap the results-archive work already fixed for deleting a single event/session also applies to "Rensa data" (Settings -> Clear data): the drivers/cars/races/all-competition-data scopes all reset resultsBySession for every current session, not just ones tied to the cleared scope, so every session's raw rows became orphaned at once. clearDataScope now purges those sessions' rows too, through the same /api/passings/purge endpoint. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
33
src/app.js
33
src/app.js
@@ -1729,6 +1729,16 @@ const TRANSLATIONS = {
|
||||
"guide.training_24": "24. Ljudhändelsen training stable pace ger valbar personlig röstfeedback efter fem kontrollerade varv i samma practice-stint. Den använder förarens uppläsningsnamn, har två minuters cooldown och aktiveras separat under Raceljud och utrop.",
|
||||
"guide.training_25": "25. Kontrollzonen går från personbästa till 8 procent långsammare. Flytserier bryts vid avvikande varv, ny stint eller ny session. Stark avslutning, rena femminuterspass och förbättrade mellantider ger positiv feedback men påverkar aldrig race-resultat.",
|
||||
"guide.training_26": "26. Under Mål och mobilprofil väljer du vilka publika sektioner som visas. Stints/prestation innehåller även biländring och tempo per aktivt 30-minutersblock. Öppna sektioner ligger kvar vid live-uppdatering.",
|
||||
"guide.training_27": "27. Under Träning kan du för vald förare/klass ställa in de två guidade övningarna \"Jämna varv\" (måltid, tolerans och antal varv i följd) och \"Stegträning\" (lugn/kontrollerad/snabb-sekvens). Båda körs inuti den redan aktiva Open Practice-sessionen utan att störa andra förare eller starta om timingen.",
|
||||
"guide.training_28": "28. Samma två övningar går även att ställa in, starta och stoppa direkt från förarens egna mobillänk, oberoende av om adminsidan har Träning öppen. Livestatus (aktuell serie eller steg) visas där föraren själv kör.",
|
||||
"guide.training_29": "29. När förarens 5-minuterstimer i mobillänken tar slut visas automatiskt en sammanfattning: tempo och jämnhet jämfört med tidigare pass, uppnådda mål eller varvmilstolpar med belöningstext, och ett förslag på nästa mål. Sammanfattningen döljs med Stäng och dyker upp igen efter nästa avslutade pass.",
|
||||
"guide.archive_title": "Resultatarkiv",
|
||||
"guide.card_archive_blurb": "Sök och öppna avslutade race på datum, klass eller förare utan att gå via Race Setup.",
|
||||
"guide.archive_1": "1. Öppna Resultatarkiv i menyn för att se alla avslutade sessioner samlade, oavsett vilket event de tillhör.",
|
||||
"guide.archive_2": "2. Sök på event- eller sessionsnamn, eller filtrera på klass, förare och datumintervall.",
|
||||
"guide.archive_3": "3. Klicka Visa på en rad för att se resultat, straff/korrigeringar och varvhistorik per förare för den sessionen.",
|
||||
"guide.archive_4": "4. Exportera samma PDF- och racepaket (JSON)-filer som redan finns i Manage Event, direkt från arkivet.",
|
||||
"guide.archive_5": "5. Att radera ett event eller en session tar bort racets data överallt, inklusive de råa varvraderna i databasen - men påverkar aldrig förarens beständiga träningsstatistik, som redan sparas separat.",
|
||||
"overlay.title": "Overlay",
|
||||
"overlay.subtitle": "Extern leaderboard-skärm",
|
||||
"overlay.no_active": "Ingen aktiv session vald.",
|
||||
@@ -1806,11 +1816,11 @@ const TRANSLATIONS = {
|
||||
"guide.linux_3": "3. Kör `npm install`, `npm start`. Servern lyssnar på 0.0.0.0:8081. `ammc-sim` kan användas som fake decoder för test med egna transponder-ID:n; se decoder-guiden.",
|
||||
"guide.sqlite_title": "SQLite-lagring",
|
||||
"guide.sqlite_1": "Databasfil: data/rc_timing.sqlite",
|
||||
"guide.sqlite_2": "API: /api/state och /api/passings",
|
||||
"guide.sqlite_2": "API: /api/state, /api/passings och /api/passings/purge",
|
||||
"guide.sqlite_3": "I Inställningar -> Lagring kan du exportera hela racepaket för backup eller flytt till annan server/laptop.",
|
||||
"guide.sqlite_4": "Du kan också exportera eller importera bara klasser, förare och bilar om du vill börja om med race men behålla registret.",
|
||||
"guide.sqlite_5": "CSV-filer för förare och bilar kan både exporteras och importeras. För förare räcker name/namn, transponder och class/klass; endast namnet är obligatoriskt. Egna exporter bevarar ID:n och externa listor slås ihop på transponder eller namn och klass.",
|
||||
"guide.sqlite_6": "Rensa data kan tömma förare, bilar, klasser, race eller träningsstatistik separat. Rensa all tävlingsdata behåller decoder-, tema-, branding- och serverinställningar. Råa SQLite-passeringar behålls som revisionslogg. Exportera backup först.",
|
||||
"guide.sqlite_6": "Rensa data kan tömma förare, bilar, klasser, race eller träningsstatistik separat. Rensa all tävlingsdata behåller decoder-, tema-, branding- och serverinställningar. Att radera ett race, en session eller rensa förare/bilar/all tävlingsdata tar även bort de råa SQLite-passeringarna för berörda sessioner - förarens beständiga träningsstatistik påverkas aldrig. Exportera backup först.",
|
||||
"guide.ammc_ref": "AMMC referens: https://www.ammconverter.eu/docs/intro/quick-start/",
|
||||
"error.backend_offline": "Backend offline: {msg}",
|
||||
"error.sync_failed": "Synk misslyckades: {msg}",
|
||||
@@ -3176,6 +3186,16 @@ const TRANSLATIONS = {
|
||||
"guide.training_24": "24. The training stable pace audio event provides optional personal voice feedback after five controlled laps in one practice stint. It uses the driver spoken name, has a two-minute cooldown, and can be enabled separately under Race sounds and announcements.",
|
||||
"guide.training_25": "25. The control zone runs from the personal best to 8 percent slower. Flow streaks reset on an outlier lap, a new stint, or a new session. Strong finishes, clean five-minute runs, and improved split times provide positive feedback but never affect race results.",
|
||||
"guide.training_26": "26. Under Goals and mobile profile, choose which public sections are visible. Stints/performance also contains car-change marking and pace per active 30-minute block. Open sections remain open during live updates.",
|
||||
"guide.training_27": "27. Under Training, for the selected driver/class, you can configure the two guided exercises \"Jämna varv\" (even laps: target lap time, tolerance and lap count) and \"Stegträning\" (step training: calm/controlled/fast sequence). Both run inside the already-active Open Practice session without disturbing other drivers or restarting timing.",
|
||||
"guide.training_28": "28. Both exercises can also be configured, started and stopped directly from the driver's own mobile link, independent of whether the admin side has Training open. Live status (current streak or step) is shown where the driver is actually running.",
|
||||
"guide.training_29": "29. When the driver's 5-minute timer on the mobile link finishes, a summary appears automatically: pace and consistency compared to recent sessions, any goal or lap milestone reached with its reward text, and one suggested next goal. The summary is dismissed with Close and reappears after the next finished pass.",
|
||||
"guide.archive_title": "Results archive",
|
||||
"guide.card_archive_blurb": "Search and open completed races by date, class or driver without going through Race Setup.",
|
||||
"guide.archive_1": "1. Open Results archive in the menu to see every completed session in one place, regardless of which event it belongs to.",
|
||||
"guide.archive_2": "2. Search by event or session name, or filter by class, driver and date range.",
|
||||
"guide.archive_3": "3. Click View on a row to see that session's results, penalties/corrections and per-driver lap history.",
|
||||
"guide.archive_4": "4. Export the same PDF and race-package (JSON) files already available in Manage Event, directly from the archive.",
|
||||
"guide.archive_5": "5. Deleting an event or session removes the race's data everywhere, including the raw lap rows in the database - but never affects a driver's durable training statistics, which are already stored separately.",
|
||||
"overlay.title": "Overlay",
|
||||
"overlay.subtitle": "External leaderboard screen",
|
||||
"overlay.no_active": "No active session selected.",
|
||||
@@ -3253,11 +3273,11 @@ const TRANSLATIONS = {
|
||||
"guide.linux_3": "3. Run `npm install`, `npm start`. Server listens on 0.0.0.0:8081. `ammc-sim` can act as a fake decoder with selected transponder IDs; see the decoder guide.",
|
||||
"guide.sqlite_title": "SQLite storage",
|
||||
"guide.sqlite_1": "Database file: data/rc_timing.sqlite",
|
||||
"guide.sqlite_2": "API endpoints: /api/state and /api/passings",
|
||||
"guide.sqlite_2": "API endpoints: /api/state, /api/passings and /api/passings/purge",
|
||||
"guide.sqlite_3": "In Settings -> Storage you can export a full race package for backup or moving to another server or laptop.",
|
||||
"guide.sqlite_4": "You can also export or import only classes, drivers and cars if you want to reset race data but keep the directory.",
|
||||
"guide.sqlite_5": "Driver and car CSV files can both be exported and imported. Drivers only need name, transponder, and class; only name is required. Native exports preserve IDs and external lists merge by transponder or by name and class.",
|
||||
"guide.sqlite_6": "Clear data can remove drivers, cars, classes, races, or training statistics separately. Clear all competition data retains decoder, theme, branding, and server settings. Raw SQLite passings remain as an audit log. Export a backup first.",
|
||||
"guide.sqlite_6": "Clear data can remove drivers, cars, classes, races, or training statistics separately. Clear all competition data retains decoder, theme, branding, and server settings. Deleting a race or session, or clearing drivers/cars/all competition data, also removes the raw SQLite passing rows for the affected sessions - a driver's durable training statistics are never affected. Export a backup first.",
|
||||
"guide.ammc_ref": "AMMC reference: https://www.ammconverter.eu/docs/intro/quick-start/",
|
||||
"error.backend_offline": "Backend offline: {msg}",
|
||||
"error.sync_failed": "Sync failed: {msg}",
|
||||
@@ -4198,6 +4218,10 @@ function importDirectoryCsv(text, type) {
|
||||
}
|
||||
|
||||
function clearDataScope(scope) {
|
||||
// drivers/cars/races/all all reset resultsBySession entirely below (not scoped to just the
|
||||
// affected driver/car), so the raw SQLite passing rows behind every current session become
|
||||
// orphaned the same way a single deleted event/session's rows would - purge them all here too.
|
||||
const sessionIdsBeforeClear = state.sessions.map((session) => session.id);
|
||||
const clearDriverReferences = () => {
|
||||
state.events = state.events.map((event) => ({
|
||||
...event,
|
||||
@@ -4265,6 +4289,7 @@ function clearDataScope(scope) {
|
||||
settingsStorageNotice = t("settings.clear_success");
|
||||
settingsStorageNoticeIsError = false;
|
||||
saveState();
|
||||
if (["drivers", "cars", "races", "all"].includes(scope)) void purgeSessionPassings(sessionIdsBeforeClear);
|
||||
renderNav();
|
||||
renderView();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ export function renderGuideView({ dom, t }) {
|
||||
${renderGuideOverviewCard("guide.race_day_title", "guide.card_race_day_blurb", { t })}
|
||||
${renderGuideOverviewCard("guide.team_title", "guide.card_team_blurb", { t })}
|
||||
${renderGuideOverviewCard("guide.training_title", "guide.card_training_blurb", { t })}
|
||||
${renderGuideOverviewCard("guide.archive_title", "guide.card_archive_blurb", { t })}
|
||||
${renderGuideOverviewCard("guide.windows_title", "guide.card_decoder_blurb", { t })}
|
||||
</div>
|
||||
</div>
|
||||
@@ -69,7 +70,11 @@ export function renderGuideView({ dom, t }) {
|
||||
|
||||
<div class="guide-section-grid mt-16">
|
||||
${renderGuidePanel("guide.dashboard_title", ["guide.dashboard_1", "guide.dashboard_2", "guide.dashboard_3", "guide.dashboard_4"], "", { t })}
|
||||
${renderGuidePanel("guide.training_title", ["guide.training_1", "guide.training_2", "guide.training_3", "guide.training_4", "guide.training_5", "guide.training_6", "guide.training_7", "guide.training_8", "guide.training_9", "guide.training_10", "guide.training_11", "guide.training_12", "guide.training_13", "guide.training_14", "guide.training_15", "guide.training_16", "guide.training_17", "guide.training_18", "guide.training_19", "guide.training_20", "guide.training_21", "guide.training_22", "guide.training_23", "guide.training_24", "guide.training_25", "guide.training_26"], "", { t })}
|
||||
${renderGuidePanel("guide.training_title", ["guide.training_1", "guide.training_2", "guide.training_3", "guide.training_4", "guide.training_5", "guide.training_6", "guide.training_7", "guide.training_8", "guide.training_9", "guide.training_10", "guide.training_11", "guide.training_12", "guide.training_13", "guide.training_14", "guide.training_15", "guide.training_16", "guide.training_17", "guide.training_18", "guide.training_19", "guide.training_20", "guide.training_21", "guide.training_22", "guide.training_23", "guide.training_24", "guide.training_25", "guide.training_26", "guide.training_27", "guide.training_28", "guide.training_29"], "", { t })}
|
||||
</div>
|
||||
|
||||
<div class="guide-section-grid mt-16">
|
||||
${renderGuidePanel("guide.archive_title", ["guide.archive_1", "guide.archive_2", "guide.archive_3", "guide.archive_4", "guide.archive_5"], "", { t })}
|
||||
</div>
|
||||
|
||||
<div class="guide-section-grid mt-16">
|
||||
|
||||
Reference in New Issue
Block a user