Files
App/www/map-import.js
HiepLM 819323f8c8
Some checks failed
Test / test (push) Has been cancelled
add function map viewer
2026-06-20 10:53:49 +07:00

98 lines
2.7 KiB
JavaScript

(() => {
const t = (key, vars) => window.I18n?.t(key, vars) ?? key;
function fileStem(name) {
const base = String(name).replace(/^.*[/\\]/, "");
const dot = base.lastIndexOf(".");
return dot >= 0 ? base.slice(0, dot) : base;
}
function isYamlFile(file) {
return /\.ya?ml$/i.test(file.name);
}
function isMapImageFile(file) {
return /\.(png|pgm)$/i.test(file.name);
}
async function matchRosMapFiles(fileList) {
const files = Array.from(fileList || []);
const yamlFile = files.find(isYamlFile);
if (!yamlFile) {
throw new Error(t("maps.importNeedYaml"));
}
let imageFile = files.find((f) => f !== yamlFile && isMapImageFile(f));
try {
const yamlText = await yamlFile.text();
const imageRef = yamlText.match(/^image:\s*(\S+)/m)?.[1];
if (imageRef) {
const refStem = fileStem(imageRef);
const matched = files.find(
(f) => f !== yamlFile && isMapImageFile(f) && fileStem(f.name) === refStem,
);
if (matched) imageFile = matched;
}
} catch {
/* best-effort stem match */
}
if (!imageFile) {
throw new Error(t("maps.importNeedImage"));
}
return { yamlFile, imageFile };
}
function buildFormData(yamlFile, imageFile, extras = {}) {
const form = new FormData();
form.append("yaml", yamlFile, yamlFile.name);
form.append("image", imageFile, imageFile.name);
Object.entries(extras).forEach(([key, value]) => {
if (value != null && value !== "") form.append(key, value);
});
return form;
}
async function apiImport(path, form) {
const res = await fetch(path, { method: "POST", credentials: "include", body: form });
if (!res.ok) {
let msg = res.statusText;
try {
const err = await res.json();
if (err.error) msg = err.error;
} catch {
/* ignore */
}
throw new Error(msg);
}
return res.json();
}
async function importNewMap(fileList, extras = {}) {
const { yamlFile, imageFile } = await matchRosMapFiles(fileList);
const form = buildFormData(yamlFile, imageFile, {
name: extras.name || fileStem(yamlFile.name),
site_id: extras.site_id || "",
created_by: extras.created_by || "",
description: extras.description || "",
});
return apiImport("/api/maps/import", form);
}
async function importOverwriteMap(mapId, fileList) {
const { yamlFile, imageFile } = await matchRosMapFiles(fileList);
const form = buildFormData(yamlFile, imageFile);
return apiImport(`/api/maps/${encodeURIComponent(mapId)}/import`, form);
}
window.MapImport = {
fileStem,
isYamlFile,
isMapImageFile,
matchRosMapFiles,
importNewMap,
importOverwriteMap,
};
})();