diff --git a/server/pruef-backstage-import.mjs b/server/pruef-backstage-import.mjs index fc65afd6..532f333e 100644 --- a/server/pruef-backstage-import.mjs +++ b/server/pruef-backstage-import.mjs @@ -397,6 +397,65 @@ console.log("\n=== Die Seite ==="); ok(/Backstage/.test(netzSatz), "unter den Knöpfen steht dauerhaft, woher die Zahlen kommen"); + /* ---- EINE EXCEL-DATEI IST EINE SACKGASSE MIT WEGWEISER ---------- + Filipe: "meine excel datei kann ich nicht auswaehlen wieso??" + + Sie liess sich nicht einmal AUSWAEHLEN -- ausgegraut, ohne ein + Wort dazu. Jetzt laesst sie sich waehlen und bekommt eine Antwort, + die weiterhilft. + + GEPRUEFT WIRD AN EINEM ECHTEN ZIP-KOPF ("PK"), denn genau das ist + eine .xlsx. Die Erkennung haengt am INHALT, nicht an der Endung -- + deshalb heisst die Testdatei hier bewusst ".xlsx" UND traegt den + richtigen Kopf; eine Pruefung ueber die Endung waere gruen, ohne + die Erkennung je zu beruehren. */ + await seite.click("#import-oeffnen"); + await seite.waitForTimeout(300); + await seite.setInputFiles("#datei", { + name: "backstage.xlsx", + mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + buffer: Buffer.from([0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00]), + }); + await seite.waitForTimeout(600); + const xlsx = await seite.evaluate(() => ({ + text: document.getElementById("import-fehler")?.textContent || "", + vorschau: document.getElementById("vorschau")?.hidden, + los: document.getElementById("import-los")?.disabled, + feld: document.getElementById("datei")?.value || "", + })); + ok(/Excel/.test(xlsx.text), `es steht da, dass es eine Excel-Datei ist (${xlsx.text.slice(0, 50)}…)`); + ok(/Backstage-Tabelle einfügen/.test(xlsx.text), + "und welcher Knopf stattdessen hilft"); + ok(/CSV/.test(xlsx.text), "und wie man sie umspeichert"); + ok(xlsx.vorschau === true && xlsx.los === true, + "es entsteht KEINE Vorschau und der Übernehmen-Knopf bleibt gesperrt"); + ok(xlsx.feld === "", + "und das Feld ist wieder leer -- eine Datei, die nicht geht, bleibt nicht stehen"); + if (process.env.SCHIRM) { + await seite.locator("#import-dialog").screenshot( + { path: join(HIER, "pruef-import-excel.png") }); + } + + /* GEGENPROBE: Eine echte Text-Tabelle geht durch denselben Weg + weiterhin hindurch. Sonst hiesse das oben nur, dass gar nichts + mehr eingelesen wird. */ + await seite.setInputFiles("#datei", { + name: "tage.csv", + mimeType: "text/csv", + buffer: Buffer.from(`Datum;Diamanten;LIVE-Dauer (Minuten) +${gestern};1234;90 +`, "utf8"), + }); + await seite.waitForTimeout(900); + const csv = await seite.evaluate(() => ({ + fehler: document.getElementById("import-fehler")?.textContent || "", + vorschau: document.getElementById("vorschau")?.hidden, + })); + ok(csv.vorschau === false && !/Excel/.test(csv.fehler), + `eine CSV kommt weiterhin durch (Vorschau da: ${csv.vorschau === false})`); + await seite.click("#import-zu"); + await seite.waitForTimeout(250); + /* ---- DER WEG UEBER DIE TIKTOK-DATEI IST WEG (11.09.2026) -------- Filipe: "ich will keine daten von denen kriegen, nur wir." diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index 075b7aee..64591473 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -13,25 +13,25 @@ "theme_color": "#06090f", "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609111522", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609111545", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609111522", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609111545", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609111522", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609111545", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609111522", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609111545", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/js/leistung.js b/workspace/assets/js/leistung.js index 70e2ab9a..6acb200c 100644 --- a/workspace/assets/js/leistung.js +++ b/workspace/assets/js/leistung.js @@ -456,6 +456,41 @@ $('vorschau').hidden = true; $('import-los').disabled = true; + /* WAS IST DAS UEBERHAUPT FUER EINE DATEI? (11.09.2026) + + Filipe: "meine excel datei kann ich nicht auswaehlen wieso??" + + Bis heute stand im Auswahlfeld nur `.csv` -- eine .xlsx war + ausgegraut, ohne ein Wort dazu. Eine Sackgasse ohne Wegweiser + ist schlimmer als eine Absage mit Begruendung: Man sucht den + Fehler bei sich. + + Jetzt laesst sich jede Datei waehlen, und WAS sie ist, sagt der + INHALT -- nicht die Endung. Eine umbenannte Datei ist keine + andere Datei. Eine .xlsx ist in Wahrheit ein ZIP-Archiv und + beginnt mit "PK"; die alte .xls beginnt mit dem + OLE-Kennzeichen D0 CF 11 E0. + + WARUM WIR SIE NICHT EINFACH LESEN: Der Leser dahinter versteht + Text (Komma, Semikolon, Tabulator). Ein ZIP-Archiv als Text + gelesen ergibt Zeichensalat -- und der schlimmste Ausgang waere + nicht "geht nicht", sondern eine Vorschau mit Zahlen, die + irgendwo aus dem Dateikopf stammen. */ + const anfang = new Uint8Array(await datei.slice(0, 8).arrayBuffer()); + const beginnt = (...b) => b.every((x, i) => anfang[i] === x); + if (beginnt(0x50, 0x4b) || beginnt(0xd0, 0xcf, 0x11, 0xe0)) { + $('import-fehler').innerHTML = + 'Das ist eine Excel-Datei. Hier passt eine Text-Tabelle ' + + '(CSV) hinein. Zwei Wege, beide dauern keine Minute:
' + + '1. In Excel alles markieren (Strg+A), kopieren (Strg+C) – ' + + 'und statt hier den Knopf „Backstage-Tabelle einfügen" nehmen. ' + + 'Dort einfügen, fertig.
' + + '2. Oder in Excel: Datei → Speichern unter und als ' + + 'Dateityp CSV UTF-8 (durch Trennzeichen getrennt) wählen.'; + $('datei').value = ''; + return; + } + try { importText = await datei.text(); } catch { @@ -463,6 +498,13 @@ return; } + /* Eine leere Datei ist kein Lesefehler, sieht aber wie einer aus. */ + if (!importText.trim()) { + $('import-fehler').textContent = 'Die Datei ist leer.'; + $('datei').value = ''; + return; + } + /* ERST DIE VORSCHAU. Ein Import, der sofort schreibt, ist bei einer falsch zugeordneten Spalte nicht mehr zurückzuholen. */ try { diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 2aa06edf..c1ac7b6e 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - + @@ -252,10 +252,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 9909421c..dfd2f027 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -147,10 +147,10 @@ - - - - - + + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 5a6719cd..44e2e991 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -181,14 +181,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 0fb005db..27eec72f 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -89,11 +89,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index d6004f11..f8ab107d 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -12,26 +12,26 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -341,10 +341,10 @@ - - - - - + + + + + diff --git a/workspace/content.html b/workspace/content.html index 4034a81f..73b80fd4 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -179,12 +179,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/crew-index.html b/workspace/crew-index.html index bb0ab2f4..61a4ccdf 100644 --- a/workspace/crew-index.html +++ b/workspace/crew-index.html @@ -30,15 +30,15 @@ - - - + + + - + @@ -252,6 +252,6 @@ - + diff --git a/workspace/crew.webmanifest b/workspace/crew.webmanifest index 86f77415..7d89803d 100644 --- a/workspace/crew.webmanifest +++ b/workspace/crew.webmanifest @@ -13,25 +13,25 @@ "theme_color": "#06090f", "icons": [ { - "src": "/assets/img/app-symbole/crew-192.png?v=202609111522", + "src": "/assets/img/app-symbole/crew-192.png?v=202609111545", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-512.png?v=202609111522", + "src": "/assets/img/app-symbole/crew-512.png?v=202609111545", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609111522", + "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609111545", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609111522", + "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609111545", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/dateien.html b/workspace/dateien.html index 021a8d26..c25ffa27 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -108,10 +108,10 @@ - - - - - + + + + + diff --git a/workspace/index.html b/workspace/index.html index 54f8a0fa..6f4709d0 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -30,9 +30,9 @@ - - - + + + @@ -401,6 +401,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index c697db52..d34849df 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -377,11 +377,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index cc6cdc67..2d7f5533 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -332,14 +332,27 @@

Aus dem Export einlesen

- Die CSV-Datei aus TikTok LIVE Backstage. Erst siehst du, was passieren - würde – geschrieben wird erst, wenn du bestätigst. Dieselbe Datei - zweimal einzulesen richtet keinen Schaden an. + Eine Text-Tabelle (CSV) mit einer Zeile je Tag. Erst + siehst du, was passieren würde – geschrieben wird erst, wenn du + bestätigst. Dieselbe Datei zweimal einzulesen richtet keinen Schaden an. +
Eine Excel-Datei (.xlsx) passt hier + nicht hinein – dafür gibt es den Knopf „Backstage-Tabelle einfügen": + in Excel markieren, kopieren, dort einfügen.

- + +
@@ -353,10 +366,10 @@
- - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index 32c4641d..e7f320f6 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -396,10 +396,10 @@ - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index ec231d14..9395aafe 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -214,11 +214,11 @@ - - - - - - + + + + + + diff --git a/workspace/report.html b/workspace/report.html index b37a5fb3..02d5e3fb 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -106,11 +106,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index cfa82b03..a53a4d24 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -173,10 +173,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index e59b7e4e..19f28341 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -12,21 +12,21 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - + + - + @@ -674,10 +674,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index fa0da082..4abefc62 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -85,11 +85,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index d13eba2d..f4531768 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -126,10 +126,10 @@ - - - - - + + + + + diff --git a/workspace/team.html b/workspace/team.html index 3abe3786..4e7506b0 100644 --- a/workspace/team.html +++ b/workspace/team.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + @@ -110,10 +110,10 @@ - - - - - + + + + + diff --git a/workspace/teamlage.html b/workspace/teamlage.html index 2305940d..59f113a4 100644 --- a/workspace/teamlage.html +++ b/workspace/teamlage.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + - - - - + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index a96d0b3e..ff6bc8fd 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -12,22 +12,22 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -149,11 +149,11 @@ - + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index fd9188a3..17eaea38 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -190,10 +190,10 @@ - - - - - + + + + +