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 { renderDashboardView, renderClassesView, renderDriversView, renderCarsView } from "./core_views.js";
|
||||||
|
|
||||||
import { renderGuideView, renderOverlayPageView } from "./misc_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";
|
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 buildPrintBrandBlock = (branding) => buildPrintBrandBlockHelper(branding, { escapeHtml });
|
||||||
const buildRaceStartListsHtml = (event) => buildRaceStartListsHtmlHelper(event, { t, state, escapeHtml, resolveEventBranding, getSessionsForEvent, getSessionSortWeight, getClassName, buildPrintBrandBlock, getSessionGridEntries, getSessionTypeLabel, getStartModeLabel, renderTable });
|
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 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 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 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 });
|
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) {
|
function getQuickAddState(transponder) {
|
||||||
const normalized = String(transponder || "").trim();
|
const normalized = String(transponder || "").trim();
|
||||||
const driver = state.drivers.find((item) => String(item.transponder || "").trim() === normalized) || null;
|
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) {
|
function getFreePracticeSessions(eventId) {
|
||||||
return getSessionsForEvent(eventId).filter((session) => session.type === "free_practice");
|
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) {
|
function renderSimpleList(items, labelFn, idFn) {
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
return `<p>${t("common.no_entries")}</p>`;
|
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