Files
drivers_bot/web/static/data_exchange.js
VPN SaaS Dev ecfb5aa949
Some checks failed
ci / test (push) Has been cancelled
Refactor menu flows into dedicated pages
2026-05-16 11:59:09 +09:00

97 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const page = CarPassPage;
let selectedPayload = null;
function summaryItems(counts = {}) {
const labels = {
vehicles: "Автомобили",
fuel_entries: "Заправки",
service_entries: "ТО и ремонт",
expense_entries: "Расходы",
appointments: "Записи в СТО",
service_visits: "Заказ-наряды",
};
return Object.entries(labels).map(([key, label]) => `
<div class="stack-item">
<strong>${label}</strong>
<small>${page.escapeHtml(counts[key] ?? 0)}</small>
</div>
`).join("");
}
function countExport(payload) {
const vehicles = payload.vehicles || [];
return {
vehicles: vehicles.length,
fuel_entries: vehicles.reduce((sum, item) => sum + (item.fuel_entries || []).length, 0),
service_entries: vehicles.reduce((sum, item) => sum + (item.service_entries || []).length, 0),
expense_entries: vehicles.reduce((sum, item) => sum + (item.expense_entries || []).length, 0),
appointments: vehicles.reduce((sum, item) => sum + (item.appointments || []).length, 0),
service_visits: vehicles.reduce((sum, item) => sum + (item.service_visits || []).length, 0),
};
}
function renderPreview(preview) {
document.querySelector("#importSummary").innerHTML = `
${summaryItems(preview.counts)}
${preview.warnings?.length ? `<div class="tip-card warning">${preview.warnings.map(page.escapeHtml).join("<br />")}</div>` : ""}
`;
}
async function readSelectedFile() {
const file = document.querySelector("#importFile").files[0];
if (!file) throw new Error("Выберите JSON-файл");
selectedPayload = JSON.parse(await file.text());
return selectedPayload;
}
document.querySelector("#exportBtn").addEventListener("click", async (event) => {
await page.runAction(event.currentTarget, "Готовлю файл...", async () => {
const payload = await page.api("/my/export");
const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
const stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, "-");
link.href = url;
link.download = `carpass-export-${stamp}.json`;
document.body.appendChild(link);
link.click();
link.remove();
URL.revokeObjectURL(url);
document.querySelector("#exportSummary").innerHTML = summaryItems(countExport(payload));
page.toast("Экспорт подготовлен");
});
});
document.querySelector("#previewBtn").addEventListener("click", async (event) => {
await page.runAction(event.currentTarget, "Проверяю файл...", async () => {
const payload = await readSelectedFile();
const preview = await page.api("/my/import/preview", {
method: "POST",
body: JSON.stringify(payload),
});
renderPreview(preview);
page.toast("Файл проверен");
});
});
document.querySelector("#importForm").addEventListener("submit", async (event) => {
event.preventDefault();
await page.runAction(document.querySelector("#importBtn"), "Импортирую...", async () => {
const payload = selectedPayload || await readSelectedFile();
const result = await page.api("/my/import", {
method: "POST",
body: JSON.stringify(payload),
});
renderPreview(result.preview);
document.querySelector("#importSummary").insertAdjacentHTML("afterbegin", `
<div class="tip-card">
Импортировано: авто ${result.imported.vehicles_created}, заправок ${result.imported.fuel_entries}, сервисных записей ${result.imported.service_entries}, расходов ${result.imported.expense_entries}.
</div>
`);
page.toast("Импорт завершен");
});
});
page.boot(async () => {});