|
|
|
@@ -386,31 +386,57 @@ function ring(pct) {
|
|
|
|
|
/* ------------------------------------------------------------------ Karte
|
|
|
|
|
Leaflet weiterhin per CDN geladen (siehe Kopfkommentar). */
|
|
|
|
|
let MAP = null, TILE = null, LEAFLET_LADEND = null;
|
|
|
|
|
const TILES = {
|
|
|
|
|
nacht: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
|
|
|
|
tag: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
|
|
|
|
|
};
|
|
|
|
|
/* Bewusst themeunabhaengig hell: Kartendienste (Google Maps & Co.) zeigen die
|
|
|
|
|
Standard-Strassenkarte immer im hellen Stil, weil Strassen, Beschriftungen
|
|
|
|
|
und Wegfarben darauf lesbar bleiben. Die frueher bei Nacht eingeblendeten
|
|
|
|
|
dark_all-Kacheln liessen die Karte im Panel schwarz wirken. */
|
|
|
|
|
const TILE_URL = "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png";
|
|
|
|
|
const ATTR = "© OpenStreetMap · CARTO";
|
|
|
|
|
/* Satellitenansicht der Standort-Vollbildkarte (Layer-Knopf) - wie die
|
|
|
|
|
CARTO-Straßenkacheln oben ohne eigenen Schlüssel nutzbar. */
|
|
|
|
|
const SAT_TILE_URL = "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}";
|
|
|
|
|
const SAT_ATTR = "Tiles © Esri";
|
|
|
|
|
|
|
|
|
|
function leafletLaden() {
|
|
|
|
|
if (window.L) return Promise.resolve();
|
|
|
|
|
if (LEAFLET_LADEND) return LEAFLET_LADEND;
|
|
|
|
|
LEAFLET_LADEND = new Promise((resolve, reject) => {
|
|
|
|
|
const css1 = document.createElement("link");
|
|
|
|
|
css1.rel = "stylesheet";
|
|
|
|
|
css1.href = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css";
|
|
|
|
|
document.head.appendChild(css1);
|
|
|
|
|
const script = document.createElement("script");
|
|
|
|
|
script.src = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js";
|
|
|
|
|
script.onload = resolve;
|
|
|
|
|
script.onerror = reject;
|
|
|
|
|
document.head.appendChild(script);
|
|
|
|
|
const LEAFLET_CSS_URL = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css";
|
|
|
|
|
const LEAFLET_JS_URL = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js";
|
|
|
|
|
|
|
|
|
|
/* Das Leaflet-Stylesheet muss in den Shadow-Root, nicht in document.head:
|
|
|
|
|
Dokument-Styles greifen nicht in ein Shadow-DOM hinein. Lag es im Head,
|
|
|
|
|
fehlte drinnen u. a. .leaflet-tile{position:absolute} - die Kacheln flossen
|
|
|
|
|
dann als gewoehnliche Bilder untereinander (bei 8 Kacheln ueber 1000 px
|
|
|
|
|
hoch), von der Karte war nur ein schmaler Streifen zu sehen und der
|
|
|
|
|
Fahrzeugmarker landete weit unterhalb des sichtbaren Ausschnitts. Das JS
|
|
|
|
|
gehoert dagegen weiterhin in den Head, damit window.L global bleibt. */
|
|
|
|
|
function leafletCssEinhaengen() {
|
|
|
|
|
if (!ROOT || ROOT.querySelector("link[data-leaflet-css]")) return Promise.resolve();
|
|
|
|
|
return new Promise((fertig) => {
|
|
|
|
|
const css = document.createElement("link");
|
|
|
|
|
css.rel = "stylesheet";
|
|
|
|
|
css.href = LEAFLET_CSS_URL;
|
|
|
|
|
css.dataset.leafletCss = "1";
|
|
|
|
|
/* Auch bei Ladefehler weitermachen statt haengen zu bleiben - dann sieht
|
|
|
|
|
die Karte zwar wieder falsch aus, aber die Ansicht baut sich auf. */
|
|
|
|
|
css.onload = fertig;
|
|
|
|
|
css.onerror = fertig;
|
|
|
|
|
ROOT.appendChild(css);
|
|
|
|
|
});
|
|
|
|
|
return LEAFLET_LADEND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function leafletLaden() {
|
|
|
|
|
/* Bewusst bei jedem Aufruf: haengt HA das Panel neu ein, entsteht ein neuer
|
|
|
|
|
Shadow-Root ohne das Stylesheet, waehrend window.L laengst gesetzt ist. */
|
|
|
|
|
const css = leafletCssEinhaengen();
|
|
|
|
|
if (window.L) return css;
|
|
|
|
|
if (!LEAFLET_LADEND) {
|
|
|
|
|
LEAFLET_LADEND = new Promise((resolve, reject) => {
|
|
|
|
|
const script = document.createElement("script");
|
|
|
|
|
script.src = LEAFLET_JS_URL;
|
|
|
|
|
script.onload = resolve;
|
|
|
|
|
script.onerror = reject;
|
|
|
|
|
document.head.appendChild(script);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return Promise.all([css, LEAFLET_LADEND]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function mapBox() { return `<div class="mapbox"><div id="map"></div></div>`; }
|
|
|
|
@@ -437,7 +463,7 @@ function fakeTrack(a, b, n = 13) {
|
|
|
|
|
}
|
|
|
|
|
function tiles() {
|
|
|
|
|
if (!MAP || !window.L) return;
|
|
|
|
|
const url = TILES[HOST.dataset.theme];
|
|
|
|
|
const url = TILE_URL;
|
|
|
|
|
if (TILE) MAP.removeLayer(TILE);
|
|
|
|
|
TILE = window.L.tileLayer(url, { maxZoom: 19, attribution: ATTR }).addTo(MAP);
|
|
|
|
|
}
|
|
|
|
@@ -498,10 +524,15 @@ const STANDORT_PEEK_PX = 96; // sichtbarer Anteil im geschlossenen Zustand, muss
|
|
|
|
|
|
|
|
|
|
function standortBekannt() { return CAR.standortLat != null && CAR.standortLon != null; }
|
|
|
|
|
|
|
|
|
|
/* Kartenmarkierung: poi-car aus dem Audi-CI-Satz (assets/icons/poi-car.svg).
|
|
|
|
|
Die Spitze sitzt unten, deshalb ankert Leaflet am unteren Rand. */
|
|
|
|
|
/* Kartenmarkierung: poi-car aus dem CI-Satz, in den beiden gelieferten
|
|
|
|
|
Groessenvarianten - poi-car-l (48er-Raster, mehr Detail) ab 34 px, darunter
|
|
|
|
|
poi-car-s (24er-Raster). Die Nadelspitze sitzt unten, deshalb ankert Leaflet
|
|
|
|
|
am unteren Rand (siehe iconAnchor an den Aufrufstellen: Spitze bei y=45.25
|
|
|
|
|
im 48er- bzw. y=23.3 im 24er-viewBox). */
|
|
|
|
|
function fahrzeugMarkerSVG(px = 34) {
|
|
|
|
|
return `<svg viewBox="0 0 24 24" width="${px}" height="${px}" fill="none" aria-hidden="true">${CI.poiCar}</svg>`;
|
|
|
|
|
const gross = px >= 34;
|
|
|
|
|
const box = gross ? 48 : 24;
|
|
|
|
|
return `<svg viewBox="0 0 ${box} ${box}" width="${px}" height="${px}" fill="none" aria-hidden="true">${gross ? CI.poiCarL : CI.poiCar}</svg>`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fahrzustand fürs Menü: "fährt" solange die aktuelle Fahrt noch offen ist
|
|
|
|
@@ -576,7 +607,7 @@ function standortErfassenFallsNoetig() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Reverse-Geocoding über die öffentliche Nominatim-API (OpenStreetMap) -
|
|
|
|
|
wie die Kartenkacheln oben (TILES) ohne eigenen Schlüssel; bei diesem
|
|
|
|
|
wie die Kartenkacheln oben (TILE_URL) ohne eigenen Schlüssel; bei diesem
|
|
|
|
|
Aufrufvolumen (ein Fahrzeug, nur bei geöffneter Standortansicht) im Rahmen
|
|
|
|
|
der Nominatim-Nutzungsbedingungen unproblematisch, genau wie das bereits
|
|
|
|
|
dokumentierte Leaflet-über-CDN-Vorgehen (siehe AGENTS.md). Cache-Schlüssel
|
|
|
|
@@ -639,14 +670,14 @@ function standortTiles() {
|
|
|
|
|
if (SMAP_TILE) SMAP.removeLayer(SMAP_TILE);
|
|
|
|
|
SMAP_TILE = SMAP_STIL === "satellit"
|
|
|
|
|
? window.L.tileLayer(SAT_TILE_URL, { maxZoom: 19, attribution: SAT_ATTR }).addTo(SMAP)
|
|
|
|
|
: window.L.tileLayer(TILES[HOST.dataset.theme], { maxZoom: 19, attribution: ATTR }).addTo(SMAP);
|
|
|
|
|
: window.L.tileLayer(TILE_URL, { maxZoom: 19, attribution: ATTR }).addTo(SMAP);
|
|
|
|
|
}
|
|
|
|
|
function standortMarkerZeichnen() {
|
|
|
|
|
if (!SMAP || !window.L) return;
|
|
|
|
|
if (FAHRZEUG_MARKER) { SMAP.removeLayer(FAHRZEUG_MARKER); FAHRZEUG_MARKER = null; }
|
|
|
|
|
if (USER_MARKER) { SMAP.removeLayer(USER_MARKER); USER_MARKER = null; }
|
|
|
|
|
if (standortBekannt()) {
|
|
|
|
|
const icon = window.L.divIcon({ className: "fahrzeug-pin-wrap", html: `<div class="fahrzeug-pin">${fahrzeugMarkerSVG(38)}</div>`, iconSize: [38, 38], iconAnchor: [18, 36] });
|
|
|
|
|
const icon = window.L.divIcon({ className: "fahrzeug-pin-wrap", html: `<div class="fahrzeug-pin">${fahrzeugMarkerSVG(38)}</div>`, iconSize: [38, 38], iconAnchor: [19, 36] });
|
|
|
|
|
FAHRZEUG_MARKER = window.L.marker([CAR.standortLat, CAR.standortLon], { icon }).addTo(SMAP);
|
|
|
|
|
FAHRZEUG_MARKER.on("click", () => standortMenuOeffnen());
|
|
|
|
|
}
|
|
|
|
@@ -693,10 +724,10 @@ async function initVorschauMap() {
|
|
|
|
|
zoomControl: false, attributionControl: false, dragging: false,
|
|
|
|
|
scrollWheelZoom: false, doubleClickZoom: false, boxZoom: false, keyboard: false, touchZoom: false,
|
|
|
|
|
});
|
|
|
|
|
TMAP_TILE = window.L.tileLayer(TILES[HOST.dataset.theme], { maxZoom: 19, attribution: ATTR }).addTo(TMAP);
|
|
|
|
|
TMAP_TILE = window.L.tileLayer(TILE_URL, { maxZoom: 19, attribution: ATTR }).addTo(TMAP);
|
|
|
|
|
if (standortBekannt()) {
|
|
|
|
|
TMAP.setView([CAR.standortLat, CAR.standortLon], 14);
|
|
|
|
|
const icon = window.L.divIcon({ className: "fahrzeug-pin-wrap", html: `<div class="fahrzeug-pin">${fahrzeugMarkerSVG(32)}</div>`, iconSize: [32, 32], iconAnchor: [15, 30] });
|
|
|
|
|
const icon = window.L.divIcon({ className: "fahrzeug-pin-wrap", html: `<div class="fahrzeug-pin">${fahrzeugMarkerSVG(32)}</div>`, iconSize: [32, 32], iconAnchor: [15, 31] });
|
|
|
|
|
window.L.marker([CAR.standortLat, CAR.standortLon], { icon }).addTo(TMAP);
|
|
|
|
|
} else {
|
|
|
|
|
TMAP.setView(kartenMittelpunkt(), 11);
|
|
|
|
@@ -781,6 +812,9 @@ const CI = {
|
|
|
|
|
carSearch: '<path fill="currentColor" d="M1 7.8a6.16 6.16 0 0 0 6.1 6.1h.4A5.7 5.7 0 0 0 13 7.91V7.9a6.1 6.1 0 0 0-5.91-6A5.93 5.93 0 0 0 1 7.8m-1 0C0 3.92 3.23.8 7.11.9a7.1 7.1 0 0 1 6.89 7c.06 2.33-1 4.44-2.73 5.71L14.8 19H20v1.5c0 .28.22.5.5.5h2a.5.5 0 0 0 .5-.5v-7.8l-1.9-1.9-.04-.06a55 55 0 0 0-2.84-4.71c-1.42-.1-2.49-.17-3.2-.2l.04-1c.77.04 1.93.1 3.48.22l.24.02.14.2a55 55 0 0 1 2.99 4.93L24 12.3v8.2c0 .83-.67 1.5-1.5 1.5h-2a1.5 1.5 0 0 1-1.5-1.5V20h-3.55l1.67 2.54-.84.54L14.26 20 5 19.96v.54c0 .83-.67 1.5-1.5 1.5h-2A1.5 1.5 0 0 1 0 20.5v-7.08h1v7.08c0 .28.22.5.5.5h2a.5.5 0 0 0 .5-.5v-1.54l9.6.02-3.17-4.83c-.87.45-1.85.72-2.92.75H7.1c-3.88 0-7-3.13-7.1-7.09zm5.47-2.75c1.86-.12 3.37-.2 4.52-.24l.03 1c-1.08.03-2.5.1-4.24.22L4.51 8c-.27.43-.6 1-1 1.7l-.87-.48c.4-.72.74-1.3 1.03-1.76q.6-.96 1.41-2.19l.14-.2z"/>',
|
|
|
|
|
gps: '<path fill="currentColor" d="M12.5 3.51V6.5h-1V3.51a8.46 8.46 0 0 0-7.99 7.99H6.5v1H3.51a8.46 8.46 0 0 0 7.99 7.99V17.5h1v2.99a8.46 8.46 0 0 0 7.99-7.99H17.5v-1h2.99a8.46 8.46 0 0 0-7.99-7.99m0-1a9.46 9.46 0 0 1 8.99 8.99h2.01v1h-2.01a9.46 9.46 0 0 1-8.99 8.99v2.01h-1v-2.01a9.46 9.46 0 0 1-8.99-8.99H.5v-1h2.01a9.46 9.46 0 0 1 8.99-8.99V.5h1z"/>',
|
|
|
|
|
poiCar: '<path fill="currentColor" d="M3.8 8.6C3.8 4.33 7.32.8 11.5.8s7.7 3.53 7.7 7.8c0 1.11-.5 2.58-1.17 4.1a48 48 0 0 1-2.5 4.7 90 90 0 0 1-3.54 5.47l-.06.09-.02.02V23l-.41-.29-.4.29h-.01l-.02-.03-.06-.09a70 70 0 0 1-1.05-1.53 90 90 0 0 1-2.49-3.93 48 48 0 0 1-2.5-4.72C4.29 11.18 3.8 9.71 3.8 8.6m7.7 14.1-.4.29.4.57.4-.57zm0-.87a88 88 0 0 0 3.17-4.94 47 47 0 0 0 2.45-4.6A10.3 10.3 0 0 0 18.2 8.6c0-3.73-3.08-6.8-6.7-6.8a6.82 6.82 0 0 0-6.7 6.8c0 .89.4 2.18 1.08 3.69.67 1.48 1.55 3.1 2.45 4.6a89 89 0 0 0 3.17 4.94M8.77 4h5.47L17 7.35V11a1 1 0 0 1-1 1h-1.5a1 1 0 0 1-1-1h-4a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V7.32zm.46 1L7 7.68V8h2v1H7v2h1.5v-1h6v1H16V9h-2V8h2v-.29L13.76 5z"/>',
|
|
|
|
|
/* poi-car-l - grosse Variante desselben CI-Symbols (48er-Raster), fuer die
|
|
|
|
|
Fahrzeugnadel auf der Vollbildkarte. Siehe fahrzeugMarkerSVG(). */
|
|
|
|
|
poiCarL: '<path fill="currentColor" d="M9 17.5C9 9.52 15.52 3 23.5 3S38 9.52 38 17.5c0 2.04-.92 4.78-2.23 7.67a90 90 0 0 1-4.84 8.98 170 170 0 0 1-6.98 10.59l-.03.04-.01.01-.41-.29-.4.3-.02-.02-.03-.04a66 66 0 0 1-.56-.8 166 166 0 0 1-6.42-9.8 90 90 0 0 1-4.84-8.97C9.92 22.27 9 19.54 9 17.5m14.5 27-.4.3.4.55.4-.56zm0-.86a132 132 0 0 0 1.77-2.56 170 170 0 0 0 4.8-7.45 89 89 0 0 0 4.79-8.87c1.3-2.89 2.14-5.45 2.14-7.26C37 10.08 30.92 4 23.5 4S10 10.08 10 17.5c0 1.8.83 4.37 2.14 7.26a89 89 0 0 0 4.79 8.87 170 170 0 0 0 6.57 10.01M17.96 7.98A63.3 63.3 0 0 1 29.05 8l.2.02.13.16c.6.7 1.1 1.36 1.46 1.94l1.31 2.08L34 14.31v7.19c0 .83-.67 1.5-1.5 1.5h-2a1.5 1.5 0 0 1-1.5-1.5V21H18v.5c0 .83-.67 1.5-1.5 1.5h-2a1.5 1.5 0 0 1-1.5-1.5v-7.19l1.85-2.11 1.3-2.08c.37-.58.86-1.24 1.47-1.96l.13-.16.2-.02ZM15.48 13 14 14.69V15h3v1h-3v5.5c0 .28.22.5.5.5h2a.5.5 0 0 0 .5-.5V20h13v1.5c0 .28.22.5.5.5h2a.5.5 0 0 0 .5-.5V16h-3v-1h3v-.31L31.52 13zm15.36-1L30 10.65a16 16 0 0 0-1.25-1.67 62.4 62.4 0 0 0-10.5-.02 17 17 0 0 0-1.25 1.7L16.16 12zM19.3 15h8.42l1.4 1.4-.16.31c-.34.74-.65 1.32-.92 1.72-.14.2-.28.38-.42.5a.92.92 0 0 1-.61.27h-7a.92.92 0 0 1-.6-.27 2.4 2.4 0 0 1-.43-.5c-.27-.4-.58-.98-.92-1.72l-.15-.32zm.42 1-.6.6c.26.57.5.99.69 1.27.11.17.2.27.26.32l.01.01h6.86v-.01c.07-.05.16-.15.27-.32.2-.28.43-.7.7-1.27l-.6-.6h-7.6Z"/>',
|
|
|
|
|
selectAll: '<path fill="currentColor" d="M2.8 2H5v1H3v2H2V2.8a.76.76 0 0 1 .43-.71.9.9 0 0 1 .35-.09zv.5zM9 3H7V2h2zm4 0h-2V2h2zm4 0h-2V2h2zm4 0h-2V2h2.2v.5V2h.02a1 1 0 0 1 .1.01c.07.01.16.03.25.08a.76.76 0 0 1 .43.71V5h-1zM6 6h12v12H6zm1 1v10h10V7zM3 7v2H2V7zm19 0v2h-1V7zM3 11v2H2v-2zm19 0v2h-1v-2zM3 15v2H2v-2zm19 0v2h-1v-2zM3 21v-2H2v2.2a.76.76 0 0 0 .43.71.9.9 0 0 0 .35.09h.01l.01-.5v.5H5v-1zm19-2v2.2a.76.76 0 0 1-.43.71.9.9 0 0 1-.35.09h-.01l-.01-.49V22H19v-1h2v-2zM9 22H7v-1h2zm4 0h-2v-1h2zm4 0h-2v-1h2z"/>',
|
|
|
|
|
planRoute: '<path fill="currentColor" d="m18.3 7-3.65-3.65.7-.7 4.86 4.85-4.86 4.85-.7-.7L18.29 8H9.5C8.67 8 8 8.67 8 9.5V21H7V9.5A2.5 2.5 0 0 1 9.5 7z"/>',
|
|
|
|
|
upload: '<path fill="currentColor" d="M13 20h-1V9.7l-3.65 3.65-.7-.7 4.85-4.86 4.85 4.86-.7.7L13 9.71zM6 5V4h13v1z"/>',
|
|
|
|
@@ -3103,11 +3137,9 @@ function ereignisseVerdrahten() {
|
|
|
|
|
ROOT.getElementById("theme").addEventListener("click", () => {
|
|
|
|
|
themeSetzen(HOST.dataset.theme === "nacht" ? "tag" : "nacht");
|
|
|
|
|
themeIcon();
|
|
|
|
|
/* Neu zeichnen, damit auch die Leaflet-Kacheln den Stil wechseln: die
|
|
|
|
|
Kachel-URL wird beim Aufbau aus TILES[theme] gewaehlt und nicht
|
|
|
|
|
nachtraeglich aktualisiert. Ohne dies blieb die Karte bis zum naechsten
|
|
|
|
|
Backend-Update im alten Stil - seit der Dauerkarte auf der Uebersicht
|
|
|
|
|
deutlich sichtbar. */
|
|
|
|
|
/* Neu zeichnen, damit theme-abhaengige, in JS gesetzte Werte (z. B. die
|
|
|
|
|
aus --red gelesene Routenfarbe in initMap) mitziehen. Die Kacheln selbst
|
|
|
|
|
sind seit TILE_URL themeunabhaengig hell und brauchen das nicht mehr. */
|
|
|
|
|
render();
|
|
|
|
|
});
|
|
|
|
|
// Wischgeste über Pointer Events (nicht Touch Events), damit dieselbe
|
|
|
|
@@ -3153,6 +3185,9 @@ function ereignisseVerdrahten() {
|
|
|
|
|
}
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
swipeWarGezogen = true;
|
|
|
|
|
// Loeschknopf erst waehrend der Geste einblenden (siehe .swipe-delete in
|
|
|
|
|
// audi-dashboard.css) - sonst blitzt er dauerhaft an den Zeilenraendern durch.
|
|
|
|
|
swipeAktivWrap.classList.add("wischt");
|
|
|
|
|
const basis = swipeAktivWrap.classList.contains("swiped") ? -SWIPE_BREITE : 0;
|
|
|
|
|
swipeDX = Math.max(-SWIPE_BREITE - 20, Math.min(0, basis + dx));
|
|
|
|
|
const inhalt = swipeAktivWrap.querySelector(".swipe-content");
|
|
|
|
@@ -3163,6 +3198,7 @@ function ereignisseVerdrahten() {
|
|
|
|
|
if (!swipeAktivWrap) return;
|
|
|
|
|
const inhalt = swipeAktivWrap.querySelector(".swipe-content");
|
|
|
|
|
inhalt.style.transition = ""; inhalt.style.transform = "";
|
|
|
|
|
swipeAktivWrap.classList.remove("wischt");
|
|
|
|
|
if (swipeGeste === "x") {
|
|
|
|
|
if (swipeDX <= -SWIPE_BREITE / 2) { schliesseAlleSwipes(); swipeAktivWrap.classList.add("swiped"); }
|
|
|
|
|
else { swipeAktivWrap.classList.remove("swiped"); }
|
|
|
|
@@ -3510,7 +3546,21 @@ function ereignisseVerdrahten() {
|
|
|
|
|
const leser = new FileReader();
|
|
|
|
|
leser.onload = () => {
|
|
|
|
|
const base64 = leser.result.split(",")[1];
|
|
|
|
|
serviceRufen("audi_dashboard_beleg_hochladen", { pdf_base64: base64, dateiname: datei.name, tank_id: tankId });
|
|
|
|
|
// Kein serviceRufen() hier: dessen catch loggt nur in die Browser-
|
|
|
|
|
// Konsole (bei allen anderen Aufrufen ok, die reagieren auf
|
|
|
|
|
// datenLaden() statt auf den Rückgabewert) - ein rejizierter
|
|
|
|
|
// Service-Aufruf (Backend nicht erreichbar, Timeout, ...) blieb
|
|
|
|
|
// für den Beleg-Upload sonst komplett unsichtbar in der
|
|
|
|
|
// Oberfläche, obwohl der Backend-seitige Parser-Fehlerpfad selbst
|
|
|
|
|
// schon einen Fehler veröffentlicht (siehe belegverarbeitung.py).
|
|
|
|
|
HASS.callService("pyscript", "audi_dashboard_beleg_hochladen",
|
|
|
|
|
{ pdf_base64: base64, dateiname: datei.name, tank_id: tankId }
|
|
|
|
|
).catch((err) => {
|
|
|
|
|
console.error("audi_dashboard: audi_dashboard_beleg_hochladen", err);
|
|
|
|
|
belegFehler = { context: kontext, meldung: "Beleg konnte nicht hochgeladen werden" };
|
|
|
|
|
if (!tankId) belegEntwurf = null;
|
|
|
|
|
render();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
leser.readAsDataURL(datei);
|
|
|
|
|
};
|
|
|
|
|