Add CSV imports and granular competition data cleanup

This commit is contained in:
larssand
2026-08-27 17:56:50 +02:00
parent a87c64a47c
commit e5af42ce2d
9 changed files with 504 additions and 8 deletions

View File

@@ -34,6 +34,8 @@ export function renderSettings(deps) {
downloadCsvFile,
buildDriversCsvRows,
buildCarsCsvRows,
importDirectoryCsv,
clearDataScope,
buildExportMeta,
normalizeStoredRacePreset,
saveAmmcConfigToBackend,
@@ -388,13 +390,32 @@ export function renderSettings(deps) {
<p class="hint">${t("settings.storage_note_csv")}</p>
<div class="actions">
<button id="exportDriversCsv" class="btn" type="button">${t("settings.export_drivers_csv")}</button>
<button id="selectDriversCsv" class="btn" type="button">${t("settings.import_drivers_csv")}</button>
<input id="importDriversCsv" type="file" accept=".csv,text/csv,text/plain" hidden />
<button id="exportCarsCsv" class="btn" type="button">${t("settings.export_cars_csv")}</button>
<button id="selectCarsCsv" class="btn" type="button">${t("settings.import_cars_csv")}</button>
<input id="importCarsCsv" type="file" accept=".csv,text/csv,text/plain" hidden />
</div>
</div>
${settingsStorageNotice ? `<p class="${settingsStorageNoticeIsError ? "error" : "hint"}">${escapeHtml(settingsStorageNotice)}</p>` : ""}
</div>
</section>
<section class="panel mt-16 settings-danger-panel">
<div class="panel-header"><h3>${t("settings.clear_data_title")}</h3></div>
<div class="panel-body">
<p class="hint">${t("settings.clear_data_note")}</p>
<div class="actions mt-16">
<button class="btn btn-danger" type="button" data-clear-scope="drivers">${t("settings.clear_drivers")}</button>
<button class="btn btn-danger" type="button" data-clear-scope="cars">${t("settings.clear_cars")}</button>
<button class="btn btn-danger" type="button" data-clear-scope="classes">${t("settings.clear_classes")}</button>
<button class="btn btn-danger" type="button" data-clear-scope="races">${t("settings.clear_races")}</button>
<button class="btn btn-danger" type="button" data-clear-scope="training">${t("settings.clear_training")}</button>
<button class="btn btn-danger" type="button" data-clear-scope="all">${t("settings.clear_all")}</button>
</div>
</div>
</section>
<section class="panel mt-16">
<div class="panel-header"><h3>${t("settings.race_presets")}</h3></div>
<div class="panel-body">
@@ -611,6 +632,30 @@ export function renderSettings(deps) {
downloadCsvFile("live_rc_cars.csv", buildCarsCsvRows());
});
const bindCsvImport = (selectButtonId, inputId, type) => {
const input = document.getElementById(inputId);
document.getElementById(selectButtonId)?.addEventListener("click", () => input?.click());
input?.addEventListener("change", (event) => {
const fileInput = event.currentTarget;
const file = fileInput instanceof HTMLInputElement ? fileInput.files?.[0] : null;
if (!file) return;
const reader = new FileReader();
reader.onload = () => importDirectoryCsv(String(reader.result || ""), type);
reader.onerror = () => importDirectoryCsv("", type);
reader.readAsText(file);
});
};
bindCsvImport("selectDriversCsv", "importDriversCsv", "drivers");
bindCsvImport("selectCarsCsv", "importCarsCsv", "cars");
document.querySelectorAll("[data-clear-scope]").forEach((button) => {
button.addEventListener("click", () => {
const scope = String(button.dataset.clearScope || "");
if (!scope || !window.confirm(t(`settings.clear_${scope}_confirm`))) return;
clearDataScope(scope);
});
});
document.getElementById("importDirectoryData")?.addEventListener("change", (event) => {
const input = event.currentTarget;
const file = input instanceof HTMLInputElement ? input.files?.[0] : null;