Extract shared event and session helpers into module
This commit is contained in:
97
src/app.js
97
src/app.js
@@ -11,6 +11,7 @@ import { getSessionTypeLabel as getSessionTypeLabelLogic, getStatusLabel as getS
|
||||
import { renderDashboardView, renderClassesView, renderDriversView, renderCarsView } from "./core_views.js";
|
||||
|
||||
import { renderGuideView, renderOverlayPageView } from "./misc_views.js";
|
||||
import { getSessionsForEventHelper, getModeLabelHelper, normalizeStartModeHelper, getStartModeLabelHelper, getClassNameHelper, getEventNameHelper, renderAssignmentListView, renderSessionsTableView } from "./event_common.js";
|
||||
|
||||
|
||||
import { renderTimingView, renderJudgingView } from "./timing_views.js";
|
||||
@@ -101,6 +102,14 @@ const renderFinalMatrix = (event) => renderFinalMatrixHelper(event, { t, escapeH
|
||||
const buildPrintBrandBlock = (branding) => buildPrintBrandBlockHelper(branding, { escapeHtml });
|
||||
const buildRaceStartListsHtml = (event) => buildRaceStartListsHtmlHelper(event, { t, state, escapeHtml, resolveEventBranding, getSessionsForEvent, getSessionSortWeight, getClassName, buildPrintBrandBlock, getSessionGridEntries, getSessionTypeLabel, getStartModeLabel, renderTable });
|
||||
const buildRaceResultsHtml = (event) => buildRaceResultsHtmlHelper(event, { t, escapeHtml, resolveEventBranding, getClassName, buildPrintBrandBlock, renderRaceStandingsTableView, buildPracticeStandings, buildQualifyingStandings, buildFinalStandings, renderTeamRaceStandings });
|
||||
const getSessionsForEvent = (eventId) => getSessionsForEventHelper(state, eventId);
|
||||
const getModeLabel = (mode) => getModeLabelHelper(mode, { t });
|
||||
const normalizeStartMode = (mode) => normalizeStartModeHelper(mode);
|
||||
const getStartModeLabel = (mode) => getStartModeLabelHelper(mode, { t, normalizeStartMode });
|
||||
const getClassName = (classId) => getClassNameHelper(state, classId, { t });
|
||||
const getEventName = (eventId) => getEventNameHelper(state, eventId, { t });
|
||||
const renderAssignmentList = (eventId) => renderAssignmentListView(eventId, { state, t, escapeHtml, getSessionsForEvent, getSessionTypeLabel, saveState, renderAssignmentList });
|
||||
const renderSessionsTable = (sessions) => renderSessionsTableView(sessions, { t, renderTable, escapeHtml, getEventName, getSessionTypeLabel, getStatusLabel, getModeLabel });
|
||||
const buildTeamRaceResultsHtml = (event) => buildTeamRaceResultsHtmlHelper(event, { t, escapeHtml, resolveEventBranding, getClassName, buildPrintBrandBlock, buildTeamRaceStandings, renderTable, formatLap, renderTeamStintLog });
|
||||
const renderDashboard = () => renderDashboardView({ state, dom, t, backend, getActiveSession, getStatusLabel, getSessionTypeLabel, getEventName, getModeLabel, getBackendUrl, formatLap, renderSessionsTable, setCurrentView: (view) => { currentView = view; }, renderNav, renderView, connectDecoder, disconnectDecoder, openOverlayWindow, ensureAudioContext, playPassingBeep, playFinishSiren, escapeHtml });
|
||||
const renderClasses = () => renderClassesView({ state, dom, t, selectedClassEditId: () => selectedClassEditId, setSelectedClassEditId: (value) => { selectedClassEditId = value; }, uid, saveState, renderView, renderTable, escapeHtml, setFormError, bindModalShell });
|
||||
@@ -5091,50 +5100,6 @@ function renderEventManager(eventId) {
|
||||
}
|
||||
}
|
||||
|
||||
function renderAssignmentList(eventId) {
|
||||
const block = document.getElementById("assignmentList");
|
||||
if (!block) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sessions = getSessionsForEvent(eventId);
|
||||
block.innerHTML = sessions
|
||||
.map((s) => {
|
||||
const items = (s.assignments || [])
|
||||
.map((a) => {
|
||||
const driver = state.drivers.find((d) => d.id === a.driverId);
|
||||
const car = state.cars.find((c) => c.id === a.carId);
|
||||
return `
|
||||
<li>
|
||||
${escapeHtml(driver?.name || t("common.unknown_driver"))} -> ${escapeHtml(car?.name || t("common.unknown_car"))} (${escapeHtml(
|
||||
car?.transponder || "-"
|
||||
)})
|
||||
<button id="as-delete-${a.id}" class="btn btn-danger btn-mini">x</button>
|
||||
</li>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
return `
|
||||
<div class="assignment-group">
|
||||
<h4>${escapeHtml(s.name)} (${escapeHtml(getSessionTypeLabel(s.type))})</h4>
|
||||
<ul>${items || `<li>${t("events.no_assignments")}</li>`}</ul>
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
sessions.forEach((s) => {
|
||||
(s.assignments || []).forEach((a) => {
|
||||
document.getElementById(`as-delete-${a.id}`)?.addEventListener("click", () => {
|
||||
s.assignments = s.assignments.filter((x) => x.id !== a.id);
|
||||
saveState();
|
||||
renderAssignmentList(eventId);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getQuickAddState(transponder) {
|
||||
const normalized = String(transponder || "").trim();
|
||||
const driver = state.drivers.find((item) => String(item.transponder || "").trim() === normalized) || null;
|
||||
@@ -5330,30 +5295,6 @@ function renderRecentPassings(session) {
|
||||
}
|
||||
|
||||
|
||||
function getSessionsForEvent(eventId) {
|
||||
return state.sessions.filter((s) => s.eventId === eventId);
|
||||
}
|
||||
|
||||
function getModeLabel(mode) {
|
||||
return mode === "track" ? t("mode.track") : t("mode.race");
|
||||
}
|
||||
|
||||
function normalizeStartMode(mode) {
|
||||
return ["mass", "position", "staggered"].includes(String(mode || "").toLowerCase()) ? String(mode).toLowerCase() : "mass";
|
||||
}
|
||||
|
||||
function getStartModeLabel(mode) {
|
||||
return t(`events.start_mode_${normalizeStartMode(mode)}`);
|
||||
}
|
||||
|
||||
function getClassName(classId) {
|
||||
return state.classes.find((x) => x.id === classId)?.name || t("common.unknown");
|
||||
}
|
||||
|
||||
function getEventName(eventId) {
|
||||
return state.events.find((x) => x.id === eventId)?.name || t("common.unknown_event");
|
||||
}
|
||||
|
||||
function getFreePracticeSessions(eventId) {
|
||||
return getSessionsForEvent(eventId).filter((session) => session.type === "free_practice");
|
||||
}
|
||||
@@ -5710,26 +5651,6 @@ function resolveCompetitor(session, transponder) {
|
||||
};
|
||||
}
|
||||
|
||||
function renderSessionsTable(sessions) {
|
||||
if (!sessions.length) {
|
||||
return `<p>${t("session.none_yet")}</p>`;
|
||||
}
|
||||
return renderTable(
|
||||
[t("table.event"), t("table.session"), t("table.type"), t("table.status"), t("table.mode")],
|
||||
sessions.map(
|
||||
(s) => `
|
||||
<tr>
|
||||
<td>${escapeHtml(getEventName(s.eventId))}</td>
|
||||
<td>${escapeHtml(s.name)}</td>
|
||||
<td>${escapeHtml(getSessionTypeLabel(s.type))}</td>
|
||||
<td>${escapeHtml(getStatusLabel(s.status))}</td>
|
||||
<td>${getModeLabel(s.mode)}</td>
|
||||
</tr>
|
||||
`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function renderSimpleList(items, labelFn, idFn) {
|
||||
if (!items.length) {
|
||||
return `<p>${t("common.no_entries")}</p>`;
|
||||
|
||||
87
src/event_common.js
Normal file
87
src/event_common.js
Normal file
@@ -0,0 +1,87 @@
|
||||
export function getSessionsForEventHelper(state, eventId) {
|
||||
return state.sessions.filter((s) => s.eventId === eventId);
|
||||
}
|
||||
|
||||
export function getModeLabelHelper(mode, { t }) {
|
||||
return mode === "track" ? t("mode.track") : t("mode.race");
|
||||
}
|
||||
|
||||
export function normalizeStartModeHelper(mode) {
|
||||
return ["mass", "position", "staggered"].includes(String(mode || "").toLowerCase()) ? String(mode).toLowerCase() : "mass";
|
||||
}
|
||||
|
||||
export function getStartModeLabelHelper(mode, { t, normalizeStartMode }) {
|
||||
return t(`events.start_mode_${normalizeStartMode(mode)}`);
|
||||
}
|
||||
|
||||
export function getClassNameHelper(state, classId, { t }) {
|
||||
return state.classes.find((x) => x.id === classId)?.name || t("common.unknown");
|
||||
}
|
||||
|
||||
export function getEventNameHelper(state, eventId, { t }) {
|
||||
return state.events.find((x) => x.id === eventId)?.name || t("common.unknown_event");
|
||||
}
|
||||
|
||||
export function renderAssignmentListView(eventId, deps) {
|
||||
const { state, t, escapeHtml, getSessionsForEvent, getSessionTypeLabel, saveState, renderAssignmentList } = deps;
|
||||
const block = document.getElementById("assignmentList");
|
||||
if (!block) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sessions = getSessionsForEvent(eventId);
|
||||
block.innerHTML = sessions
|
||||
.map((s) => {
|
||||
const items = (s.assignments || [])
|
||||
.map((a) => {
|
||||
const driver = state.drivers.find((d) => d.id === a.driverId);
|
||||
const car = state.cars.find((c) => c.id === a.carId);
|
||||
return `
|
||||
<li>
|
||||
${escapeHtml(driver?.name || t("common.unknown_driver"))} -> ${escapeHtml(car?.name || t("common.unknown_car"))} (${escapeHtml(car?.transponder || "-")})
|
||||
<button id="as-delete-${a.id}" class="btn btn-danger btn-mini">x</button>
|
||||
</li>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
return `
|
||||
<div class="assignment-group">
|
||||
<h4>${escapeHtml(s.name)} (${escapeHtml(getSessionTypeLabel(s.type))})</h4>
|
||||
<ul>${items || `<li>${t("events.no_assignments")}</li>`}</ul>
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
sessions.forEach((s) => {
|
||||
(s.assignments || []).forEach((a) => {
|
||||
document.getElementById(`as-delete-${a.id}`)?.addEventListener("click", () => {
|
||||
s.assignments = s.assignments.filter((x) => x.id !== a.id);
|
||||
saveState();
|
||||
renderAssignmentList(eventId);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function renderSessionsTableView(sessions, deps) {
|
||||
const { t, renderTable, escapeHtml, getEventName, getSessionTypeLabel, getStatusLabel, getModeLabel } = deps;
|
||||
if (!sessions.length) {
|
||||
return `<p>${t("session.none_yet")}</p>`;
|
||||
}
|
||||
return renderTable(
|
||||
[t("table.event"), t("table.session"), t("table.type"), t("table.status"), t("table.mode")],
|
||||
sessions.map(
|
||||
(s) => `
|
||||
<tr>
|
||||
<td>${escapeHtml(getEventName(s.eventId))}</td>
|
||||
<td>${escapeHtml(s.name)}</td>
|
||||
<td>${escapeHtml(getSessionTypeLabel(s.type))}</td>
|
||||
<td>${escapeHtml(getStatusLabel(s.status))}</td>
|
||||
<td>${getModeLabel(s.mode)}</td>
|
||||
</tr>
|
||||
`
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user