Refine race setup summary and preset-aware basic mode
This commit is contained in:
@@ -41,6 +41,7 @@ JMK RB RaceController is an RC timing and race-control system with support for s
|
|||||||
- Basic mode now reacts to the selected preset, including a cleaner endurance view
|
- Basic mode now reacts to the selected preset, including a cleaner endurance view
|
||||||
- `Basic / Advanced` mode for `Race Format`
|
- `Basic / Advanced` mode for `Race Format`
|
||||||
- a right-side race summary card
|
- a right-side race summary card
|
||||||
|
- a preset-aware summary card that changes between endurance and normal race focus
|
||||||
- separate `Race actions` for generation, reseeding and bump-up
|
- separate `Race actions` for generation, reseeding and bump-up
|
||||||
- reorganized in-app `Guide` with overview cards and two-column sections
|
- reorganized in-app `Guide` with overview cards and two-column sections
|
||||||
- explicit race participant selection
|
- explicit race participant selection
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ RC timing app med sponsor-eventflöde (delade bilar/transpondrar mellan olika he
|
|||||||
- Grundläge reagerar nu på valt preset, inklusive renare endurance-vy
|
- Grundläge reagerar nu på valt preset, inklusive renare endurance-vy
|
||||||
- `Grundläge / Avancerat` för `Raceformat`
|
- `Grundläge / Avancerat` för `Raceformat`
|
||||||
- en sammanfattningspanel till höger
|
- en sammanfattningspanel till höger
|
||||||
|
- ett presetstyrt sammanfattningskort som växlar mellan endurance- och vanligt race-fokus
|
||||||
- separata `Race actions` för generering, reseeding och bump-up
|
- separata `Race actions` för generering, reseeding och bump-up
|
||||||
- omgjord inbyggd `Guide` med översiktskort och tvåkolumnslayout
|
- omgjord inbyggd `Guide` med översiktskort och tvåkolumnslayout
|
||||||
- välj exakt vilka förare som är med i racet
|
- välj exakt vilka förare som är med i racet
|
||||||
|
|||||||
17
src/app.js
17
src/app.js
@@ -193,6 +193,8 @@ const TRANSLATIONS = {
|
|||||||
"events.race_summary_finals": "Finalupplägg",
|
"events.race_summary_finals": "Finalupplägg",
|
||||||
"events.race_summary_validation": "Varvfönster",
|
"events.race_summary_validation": "Varvfönster",
|
||||||
"events.race_summary_follow_up": "Follow-up",
|
"events.race_summary_follow_up": "Follow-up",
|
||||||
|
"events.race_summary_focus": "Fokus",
|
||||||
|
"events.race_summary_generation": "Generering",
|
||||||
"events.race_actions_title": "Race actions",
|
"events.race_actions_title": "Race actions",
|
||||||
"events.race_actions_hint": "Generering och reseeding ligger separat från formatinställningarna så setupen blir lättare att läsa.",
|
"events.race_actions_hint": "Generering och reseeding ligger separat från formatinställningarna så setupen blir lättare att läsa.",
|
||||||
"events.context_standard_title": "Klubbrace-läge",
|
"events.context_standard_title": "Klubbrace-läge",
|
||||||
@@ -907,6 +909,8 @@ const TRANSLATIONS = {
|
|||||||
"events.race_summary_finals": "Finals setup",
|
"events.race_summary_finals": "Finals setup",
|
||||||
"events.race_summary_validation": "Lap window",
|
"events.race_summary_validation": "Lap window",
|
||||||
"events.race_summary_follow_up": "Follow-up",
|
"events.race_summary_follow_up": "Follow-up",
|
||||||
|
"events.race_summary_focus": "Focus",
|
||||||
|
"events.race_summary_generation": "Generation",
|
||||||
"events.race_actions_title": "Race actions",
|
"events.race_actions_title": "Race actions",
|
||||||
"events.race_actions_hint": "Generation and reseeding live separately from the format fields so setup is easier to read.",
|
"events.race_actions_hint": "Generation and reseeding live separately from the format fields so setup is easier to read.",
|
||||||
"events.context_standard_title": "Club race mode",
|
"events.context_standard_title": "Club race mode",
|
||||||
@@ -7712,12 +7716,25 @@ function getRaceSummaryItems(event, sessions, raceDrivers, selectedPreset) {
|
|||||||
const teamCount = sessions.filter((session) => session.type === "team_race").length;
|
const teamCount = sessions.filter((session) => session.type === "team_race").length;
|
||||||
const scoringLabel = cfg.qualifyingScoring === "best" ? t("events.qualifying_scoring_best") : t("events.qualifying_scoring_points");
|
const scoringLabel = cfg.qualifyingScoring === "best" ? t("events.qualifying_scoring_best") : t("events.qualifying_scoring_points");
|
||||||
const lapWindow = `${((cfg.minLapMs || 0) / 1000).toFixed(1)}s / ${((cfg.maxLapMs || 0) / 1000).toFixed(1)}s`;
|
const lapWindow = `${((cfg.minLapMs || 0) / 1000).toFixed(1)}s / ${((cfg.maxLapMs || 0) / 1000).toFixed(1)}s`;
|
||||||
|
const isEndurancePreset = selectedPreset?.id === "endurance";
|
||||||
|
if (isEndurancePreset) {
|
||||||
|
return [
|
||||||
|
{ label: t("events.race_summary_preset"), value: selectedPreset?.label || t("events.preset_custom") },
|
||||||
|
{ label: t("events.race_summary_focus"), value: `${t("events.team_race")} · ${getStartModeLabel("mass")}` },
|
||||||
|
{ label: t("events.race_summary_participants"), value: String(participantCount || 0) },
|
||||||
|
{ label: t("events.race_summary_created_sessions"), value: `P ${practiceCount} · T ${teamCount}` },
|
||||||
|
{ label: t("events.race_summary_generation"), value: `${teamCount ? t("events.team_race") : t("events.wizard_use_team_race")} · ${cfg.finalDurationMin || 0} min` },
|
||||||
|
{ label: t("events.race_summary_validation"), value: lapWindow },
|
||||||
|
{ label: t("events.race_summary_follow_up"), value: `${cfg.followUpSec || 0}s` },
|
||||||
|
];
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
{ label: t("events.race_summary_preset"), value: selectedPreset?.label || t("events.preset_custom") },
|
{ label: t("events.race_summary_preset"), value: selectedPreset?.label || t("events.preset_custom") },
|
||||||
{ label: t("events.race_summary_participants"), value: String(participantCount || 0) },
|
{ label: t("events.race_summary_participants"), value: String(participantCount || 0) },
|
||||||
{ label: t("events.race_summary_created_sessions"), value: `P ${practiceCount} · Q ${qualCount} · F ${finalCount} · T ${teamCount}` },
|
{ label: t("events.race_summary_created_sessions"), value: `P ${practiceCount} · Q ${qualCount} · F ${finalCount} · T ${teamCount}` },
|
||||||
{ label: t("events.race_summary_qualifying"), value: `${cfg.qualifyingRounds || 0} x ${cfg.qualDurationMin || 0} min · ${cfg.carsPerHeat || 0}/heat · ${scoringLabel}` },
|
{ label: t("events.race_summary_qualifying"), value: `${cfg.qualifyingRounds || 0} x ${cfg.qualDurationMin || 0} min · ${cfg.carsPerHeat || 0}/heat · ${scoringLabel}` },
|
||||||
{ label: t("events.race_summary_finals"), value: `${cfg.carsPerFinal || 0}/main · ${cfg.finalLegs || 0} leg · ${getStartModeLabel(cfg.finalStartMode || "position")}` },
|
{ label: t("events.race_summary_finals"), value: `${cfg.carsPerFinal || 0}/main · ${cfg.finalLegs || 0} leg · ${getStartModeLabel(cfg.finalStartMode || "position")}` },
|
||||||
|
{ label: t("events.race_summary_generation"), value: `${cfg.finalsSource === "practice" ? t("events.finals_from_practice") : t("events.finals_from_qualifying")} · bump ${cfg.bumpCount || 0}` },
|
||||||
{ label: t("events.race_summary_validation"), value: lapWindow },
|
{ label: t("events.race_summary_validation"), value: lapWindow },
|
||||||
{ label: t("events.race_summary_follow_up"), value: `${cfg.followUpSec || 0}s` },
|
{ label: t("events.race_summary_follow_up"), value: `${cfg.followUpSec || 0}s` },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -514,6 +514,16 @@ body {
|
|||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.race-summary-card {
|
||||||
|
position: sticky;
|
||||||
|
top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.race-summary-card .panel-body {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.panel-header-inline {
|
.panel-header-inline {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user