diff --git a/srv/tesm/VERSION b/srv/tesm/VERSION index 45a1b3f..781dcb0 100644 --- a/srv/tesm/VERSION +++ b/srv/tesm/VERSION @@ -1 +1 @@ -1.1.2 +1.1.3 diff --git a/srv/tesm/app.py b/srv/tesm/app.py index 8281c5b..f035d7e 100644 --- a/srv/tesm/app.py +++ b/srv/tesm/app.py @@ -2289,18 +2289,31 @@ def fileshare_upload(): return redirect(url_for("fileshare", share=share, path=rel_path)) abs_dir = _fileshare_resolve_path(share, rel_path) - file = request.files.get("file") - if not abs_dir or not os.path.isdir(abs_dir) or not file or not file.filename: + # request.files.getlist() statt .get(): das Upload-Feld erlaubt jetzt + # Mehrfachauswahl (name="file" multiple) -- ein einzelner Dateiauswahl- + # Dialog liefert dann mehrere Files unter demselben Feldnamen, klassisch + # eine Datei liefert genauso eine Liste mit einem Element. + files = [f for f in request.files.getlist("file") if f and f.filename] + if not abs_dir or not os.path.isdir(abs_dir) or not files: flash("Ungültiges Ziel oder keine Datei ausgewählt.", "danger") else: - filename = secure_filename(file.filename) - dest = os.path.join(abs_dir, filename) if filename else None - if not filename or os.path.dirname(os.path.realpath(dest)) != os.path.realpath(abs_dir): - flash("Ungültiger Dateiname.", "danger") - else: + uploaded, rejected = [], [] + for file in files: + filename = secure_filename(file.filename) + dest = os.path.join(abs_dir, filename) if filename else None + if not filename or os.path.dirname(os.path.realpath(dest)) != os.path.realpath(abs_dir): + rejected.append(file.filename) + continue file.save(dest) - log_action("fileshare.upload", share, f"{rel_path}/{filename}".strip("/")) - flash(f"„{filename}“ hochgeladen.", "success") + uploaded.append(filename) + if uploaded: + log_action("fileshare.upload", share, f"{rel_path}/".strip("/") + f" ({len(uploaded)} Datei(en): {', '.join(uploaded)})") + if len(uploaded) == 1: + flash(f"„{uploaded[0]}“ hochgeladen.", "success") + else: + flash(f"{len(uploaded)} Dateien hochgeladen: {', '.join(uploaded)}.", "success") + if rejected: + flash(f"Ungültiger Dateiname, übersprungen: {', '.join(rejected)}.", "danger") return redirect(url_for("fileshare", share=share, path=rel_path)) diff --git a/srv/tesm/static/css/style.css b/srv/tesm/static/css/style.css index 530d6e5..98b328e 100644 --- a/srv/tesm/static/css/style.css +++ b/srv/tesm/static/css/style.css @@ -1360,6 +1360,24 @@ select { .xlsx-preview-sheet-title { margin: 20px 0 8px; font-size: 13px; font-weight: 650; } .xlsx-preview-sheet-title:first-child { margin-top: 0; } +/* Angesammelte Dateien im Upload-Modal (Mehrfachauswahl, siehe fileshare.html) */ +.upload-file-list { margin-top: 8px; display: flex; flex-direction: column; gap: 4px; } +.upload-file-row { + display: flex; align-items: center; justify-content: space-between; gap: 8px; + padding: 5px 10px; + background: var(--bg-elevated); + border: 1px solid var(--border-soft); + border-radius: 7px; + font-size: 12.5px; +} +.upload-file-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.upload-file-remove { + flex-shrink: 0; + border: none; background: transparent; color: var(--text-faint); + font-size: 16px; line-height: 1; cursor: pointer; padding: 0 2px; +} +.upload-file-remove:hover { color: var(--danger); } + /* ========================================================================== Utilities ========================================================================== */ @@ -1404,6 +1422,12 @@ select { Buttons/Suchfeld ineinanderzuschieben. */ .modal-footer { flex-wrap: wrap; } .table-toolbar .search-input { min-width: 0; flex: 1 1 160px; } + + /* Fileshare-Baum + Tabelle nebeneinander sprengt auf Tablet-/Handy- + Breite die Seite (Baum-Spalte ist fest 260px breit) -- Baum stapelt + stattdessen oben, Tabelle darunter in voller Breite. */ + .fileshare-layout { flex-direction: column; } + .fileshare-tree { flex: 1 1 auto; max-width: 100%; max-height: 240px; } } @media (max-width: 640px) { diff --git a/srv/tesm/templates/fileshare.html b/srv/tesm/templates/fileshare.html index 048bcac..c8d6962 100644 --- a/srv/tesm/templates/fileshare.html +++ b/srv/tesm/templates/fileshare.html @@ -140,14 +140,15 @@