diff --git a/src/app.js b/src/app.js
index ea58f27..2cb0b44 100644
--- a/src/app.js
+++ b/src/app.js
@@ -13,6 +13,7 @@ import { renderDashboardView, renderClassesView, renderDriversView, renderCarsVi
import { renderGuideView, renderOverlayPageView } from "./misc_views.js";
import { getSessionsForEventHelper, getModeLabelHelper, normalizeStartModeHelper, getStartModeLabelHelper, getClassNameHelper, getEventNameHelper, renderAssignmentListView, renderSessionsTableView } from "./event_common.js";
import { renderEventWorkspaceMarkup } from "./event_views.js";
+import { renderEventManagerMarkup } from "./event_manager_view.js";
import { createDefaultAmmcConfigHelper, getManagedWsUrlHelper, loadAmmcConfigFromBackendHelper, saveAmmcConfigToBackendHelper, refreshAmmcStatusHelper, startManagedAmmcHelper, stopManagedAmmcHelper, applyPersistedStateHelper, hydrateFromBackendHelper, scheduleBackendSyncHelper, syncStateToBackendHelper, pingBackendHelper, checkAppVersionHelper, startAppVersionPollingHelper, startOverlaySyncHelper, startOverlayRotationHelper, startOverlayLiveRefreshHelper, ensureAudioContextHelper, playPassingBeepHelper, playFinishSirenHelper, playLeaderCueHelper, playStartCueHelper, playBestLapCueHelper, pushOverlayEventHelper, speakTextHelper, announcePassingHelper, announceRaceFinishedHelper, handleSessionTimerTickHelper, tickClockHelper } from "./runtime_services.js";
import { connectDecoderHelper, disconnectDecoderHelper, processDecoderMessageHelper } from "./decoder_runtime.js";
@@ -3145,793 +3146,50 @@ function renderEventManager(eventId) {
selectedGridSessionId = selectedGridSession.id;
}
- eventManageArea.innerHTML = `
-
-
-
-
-
${t("events.seed_best_laps_hint")}
-
${t("events.free_practice_note")}
-
${t("events.open_practice_note")}
-
-
- ${renderTable(
- [t("table.session"), t("table.type"), t("table.duration"), t("table.start_mode"), t("table.seeding"), t("table.status"), t(event.mode === "track" ? "events.assignments" : "events.participants"), t("events.actions")],
- sessions.map((s) => {
- const assignCount =
- event.mode === "track"
- ? (s.assignments || []).length
- : s.type === "team_race"
- ? raceTeams.length
- : getSessionEntrants(s).length;
- return `
-
- | ${escapeHtml(s.name)} |
- ${escapeHtml(getSessionTypeLabel(s.type))} |
- ${s.durationMin} min |
- ${escapeHtml(getStartModeLabel(s.startMode))} |
- ${s.seedBestLapCount > 0 ? `${s.seedBestLapCount}` : "-"} |
- ${escapeHtml(getStatusLabel(s.status))} |
- ${assignCount || (event.mode === "track" ? t("events.na") : "-")} |
-
-
-
- ${
- event.mode === "race" && normalizeStartMode(s.startMode) === "position"
- ? ``
- : ""
- }
- ${
- event.mode === "race" && ["qualification", "final"].includes(s.type)
- ? `
-
-
-
- `
- : ""
- }
-
- |
-
- `;
- })
- )}
-
-
-
-
-
-
-
-
-
${t("events.branding_note")}
-
-
-
-
- ${branding.logoDataUrl ? `
` : ""}
-
-
-
- ${
- event.mode === "track"
- ? `
-
-
-
-
-
- ${t("events.tp_rule")}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- : ""
- }
-
- ${
- event.mode === "race"
- ? `
-
-
-
- ${t("events.manage_step_setup")}${renderManageStatusBadgeView(manageStatuses?.setup?.status || "pending")}
- ${escapeHtml(manageStatuses?.setup?.detail || "")}
- ${t("events.manage_step_setup_hint")}
-
-
- ${t("events.manage_step_format")}${renderManageStatusBadgeView(manageStatuses?.format?.status || "pending")}
- ${escapeHtml(manageStatuses?.format?.detail || "")}
- ${t("events.manage_step_format_hint")}
-
-
- ${t("events.manage_step_generate")}${renderManageStatusBadgeView(manageStatuses?.generation?.status || "pending")}
- ${escapeHtml(manageStatuses?.generation?.detail || "")}
- ${t("events.manage_step_generate_hint")}
-
-
- ${t("events.manage_step_live")}${renderManageStatusBadgeView(manageStatuses?.live?.status || "pending")}
- ${escapeHtml(manageStatuses?.live?.detail || "")}
- ${t("events.manage_step_live_hint")}
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${raceDrivers
- .map((driver) => {
- const checked = event.raceConfig.participantsConfigured
- ? (event.raceConfig.driverIds || []).includes(driver.id)
- : true;
- return `
-
- `;
- })
- .join("")}
-
-
-
-
-
-
-
-
${t("events.team_race_intro")}
-
${t("events.team_steps")}
-
-
${t("events.team_hint")}
-
-
-
- ${t("events.team_form_drivers")}
- ${teamDriverPool.fallback ? `${t("events.team_driver_fallback")}
` : ""}
-
- ${raceDrivers
- .map(
- (driver) => `
-
- `
- )
- .join("")}
-
-
-
-
-
- ${
- raceTeams.length
- ? raceTeams
- .map(
- (team) => `
-
-
-
${escapeHtml(team.name)}
-
${t("events.team_drivers")}: ${escapeHtml(
- team.driverIds.map((driverId) => getDriverDisplayById(driverId)).join(", ") || "-"
- )}
-
${t("events.team_cars")}: ${escapeHtml(
- team.carIds
- .map((carId) => {
- const car = state.cars.find((item) => item.id === carId);
- return car ? `${car.name} (${car.transponder || "-"})` : "";
- })
- .filter(Boolean)
- .join(", ") || "-"
- )}
-
-
-
-
-
-
- `
- )
- .join("")
- : `
${t("events.no_teams")}
`
- }
-
-
-
-
-
-
-
-
-
-
- ${renderGridEditor(selectedGridSession)}
-
-
-
-
-
-
- ${renderRaceStandingsTableView(buildPracticeStandings(event), t("events.no_practice_results"))}
-
-
-
-
-
-
- ${renderRaceStandingsTableView(buildQualifyingStandings(event), t("events.no_qualifying_results"))}
-
-
-
-
-
-
- ${renderRaceStandingsTableView(buildFinalStandings(event), t("events.no_final_results"))}
-
-
-
-
-
-
-
-
-
-
-
- ${renderTeamRaceStandings(event)}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${renderFinalMatrix(event)}
-
-
-
- `
- : ""
- }
-
- ${
- editingTeam
- ? `
-
- `
- : ""
- }
-
- ${
- editingSession
- ? `
-
- `
- : ""
- }
- `;
+ eventManageArea.innerHTML = renderEventManagerMarkup({
+ event,
+ t,
+ escapeHtml,
+ sessions,
+ sessionTypeChoices,
+ sessionTypeHintKey,
+ raceTeams,
+ getSessionEntrants,
+ getSessionTypeLabel,
+ getStartModeLabel,
+ getStatusLabel,
+ normalizeStartMode,
+ branding,
+ driverOptions,
+ carOptions,
+ manageStatuses,
+ renderManageStatusBadgeView,
+ selectedParticipantCount,
+ raceDrivers,
+ teamDriverPool,
+ state,
+ getDriverDisplayById,
+ raceFormatAdvanced,
+ racePresets,
+ selectedPreset,
+ isEndurancePreset,
+ renderRaceFormatContextCardView,
+ renderRaceFormatFieldView,
+ raceSummaryWarnings,
+ raceSummaryItems,
+ selectedGridSession,
+ renderGridEditor,
+ renderRaceStandingsTableView,
+ buildPracticeStandings,
+ buildQualifyingStandings,
+ buildFinalStandings,
+ renderTeamRaceStandings,
+ renderFinalMatrix,
+ editingTeam,
+ editingSession,
+ getModeLabel,
+ renderTable,
+ });
const bindManageJump = (node) => {
const triggerJump = () => {
diff --git a/src/event_manager_view.js b/src/event_manager_view.js
new file mode 100644
index 0000000..557a17d
--- /dev/null
+++ b/src/event_manager_view.js
@@ -0,0 +1,833 @@
+export function renderEventManagerMarkup(context) {
+ const {
+ event,
+ t,
+ escapeHtml,
+ sessions,
+ sessionTypeChoices,
+ sessionTypeHintKey,
+ raceTeams,
+ getSessionEntrants,
+ getSessionTypeLabel,
+ getStartModeLabel,
+ getStatusLabel,
+ normalizeStartMode,
+ branding,
+ driverOptions,
+ carOptions,
+ manageStatuses,
+ renderManageStatusBadgeView,
+ selectedParticipantCount,
+ raceDrivers,
+ teamDriverPool,
+ state,
+ getDriverDisplayById,
+ raceFormatAdvanced,
+ racePresets,
+ selectedPreset,
+ isEndurancePreset,
+ renderRaceFormatContextCardView,
+ renderRaceFormatFieldView,
+ raceSummaryWarnings,
+ raceSummaryItems,
+ selectedGridSession,
+ renderGridEditor,
+ renderRaceStandingsTableView,
+ buildPracticeStandings,
+ buildQualifyingStandings,
+ buildFinalStandings,
+ renderTeamRaceStandings,
+ renderFinalMatrix,
+ editingTeam,
+ editingSession,
+ getModeLabel,
+ renderTable,
+ } = context;
+ return `
+
+
+
+
+
${t("events.seed_best_laps_hint")}
+
${t("events.free_practice_note")}
+
${t("events.open_practice_note")}
+
+
+ ${renderTable(
+ [t("table.session"), t("table.type"), t("table.duration"), t("table.start_mode"), t("table.seeding"), t("table.status"), t(event.mode === "track" ? "events.assignments" : "events.participants"), t("events.actions")],
+ sessions.map((s) => {
+ const assignCount =
+ event.mode === "track"
+ ? (s.assignments || []).length
+ : s.type === "team_race"
+ ? raceTeams.length
+ : getSessionEntrants(s).length;
+ return `
+
+ | ${escapeHtml(s.name)} |
+ ${escapeHtml(getSessionTypeLabel(s.type))} |
+ ${s.durationMin} min |
+ ${escapeHtml(getStartModeLabel(s.startMode))} |
+ ${s.seedBestLapCount > 0 ? `${s.seedBestLapCount}` : "-"} |
+ ${escapeHtml(getStatusLabel(s.status))} |
+ ${assignCount || (event.mode === "track" ? t("events.na") : "-")} |
+
+
+
+ ${
+ event.mode === "race" && normalizeStartMode(s.startMode) === "position"
+ ? ``
+ : ""
+ }
+ ${
+ event.mode === "race" && ["qualification", "final"].includes(s.type)
+ ? `
+
+
+
+ `
+ : ""
+ }
+
+ |
+
+ `;
+ })
+ )}
+
+
+
+
+
+
+
+
+
${t("events.branding_note")}
+
+
+
+
+ ${branding.logoDataUrl ? `
` : ""}
+
+
+
+ ${
+ event.mode === "track"
+ ? `
+
+
+
+
+
+ ${t("events.tp_rule")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ : ""
+ }
+
+ ${
+ event.mode === "race"
+ ? `
+
+
+
+ ${t("events.manage_step_setup")}${renderManageStatusBadgeView(manageStatuses?.setup?.status || "pending")}
+ ${escapeHtml(manageStatuses?.setup?.detail || "")}
+ ${t("events.manage_step_setup_hint")}
+
+
+ ${t("events.manage_step_format")}${renderManageStatusBadgeView(manageStatuses?.format?.status || "pending")}
+ ${escapeHtml(manageStatuses?.format?.detail || "")}
+ ${t("events.manage_step_format_hint")}
+
+
+ ${t("events.manage_step_generate")}${renderManageStatusBadgeView(manageStatuses?.generation?.status || "pending")}
+ ${escapeHtml(manageStatuses?.generation?.detail || "")}
+ ${t("events.manage_step_generate_hint")}
+
+
+ ${t("events.manage_step_live")}${renderManageStatusBadgeView(manageStatuses?.live?.status || "pending")}
+ ${escapeHtml(manageStatuses?.live?.detail || "")}
+ ${t("events.manage_step_live_hint")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${raceDrivers
+ .map((driver) => {
+ const checked = event.raceConfig.participantsConfigured
+ ? (event.raceConfig.driverIds || []).includes(driver.id)
+ : true;
+ return `
+
+ `;
+ })
+ .join("")}
+
+
+
+
+
+
+
+
${t("events.team_race_intro")}
+
${t("events.team_steps")}
+
+
${t("events.team_hint")}
+
+
+
+ ${t("events.team_form_drivers")}
+ ${teamDriverPool.fallback ? `${t("events.team_driver_fallback")}
` : ""}
+
+ ${raceDrivers
+ .map(
+ (driver) => `
+
+ `
+ )
+ .join("")}
+
+
+
+
+
+ ${
+ raceTeams.length
+ ? raceTeams
+ .map(
+ (team) => `
+
+
+
${escapeHtml(team.name)}
+
${t("events.team_drivers")}: ${escapeHtml(
+ team.driverIds.map((driverId) => getDriverDisplayById(driverId)).join(", ") || "-"
+ )}
+
${t("events.team_cars")}: ${escapeHtml(
+ team.carIds
+ .map((carId) => {
+ const car = state.cars.find((item) => item.id === carId);
+ return car ? `${car.name} (${car.transponder || "-"})` : "";
+ })
+ .filter(Boolean)
+ .join(", ") || "-"
+ )}
+
+
+
+
+
+
+ `
+ )
+ .join("")
+ : `
${t("events.no_teams")}
`
+ }
+
+
+
+
+
+
+
+
+
+
+ ${renderGridEditor(selectedGridSession)}
+
+
+
+
+
+
+ ${renderRaceStandingsTableView(buildPracticeStandings(event), t("events.no_practice_results"))}
+
+
+
+
+
+
+ ${renderRaceStandingsTableView(buildQualifyingStandings(event), t("events.no_qualifying_results"))}
+
+
+
+
+
+
+ ${renderRaceStandingsTableView(buildFinalStandings(event), t("events.no_final_results"))}
+
+
+
+
+
+
+
+
+
+
+
+ ${renderTeamRaceStandings(event)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${renderFinalMatrix(event)}
+
+
+
+ `
+ : ""
+ }
+
+ ${
+ editingTeam
+ ? `
+
+ `
+ : ""
+ }
+
+ ${
+ editingSession
+ ? `
+
+ `
+ : ""
+ }
+ `;;
+}