This commit is contained in:
96
web/static/data_exchange.js
Normal file
96
web/static/data_exchange.js
Normal file
@@ -0,0 +1,96 @@
|
||||
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 () => {});
|
||||
Reference in New Issue
Block a user