add: wenn input folder leer -> hochladen von xlxs Dateien vereinfacht
This commit is contained in:
1 parent
7d63063024
commit
2237779e56
4 files changed
+75
-2
No files matched your search
@@ -9,6 +9,12 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
|
|||||||
|
|
||||||
## [1.3.2] – 2026-10-07
|
## [1.3.2] – 2026-10-07
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
|
||||||
|
- **Input-Dateien hinzufügen**: Bei leerem Input-Ordner können `.xlsx`-Dateien per Drag-and-drop oder Dateiauswahl in den Input-Ordner kopiert werden
|
||||||
|
- **Input-Ordner öffnen**: Ein Button öffnet den Input-Ordner direkt im Explorer
|
||||||
|
- **Input-Ordner neu einlesen**: Dateiliste kann über Button aktualisiert werden
|
||||||
|
|
||||||
### Behoben
|
### Behoben
|
||||||
|
|
||||||
- EXE erkennt laufende Entwicklungsinstanz und fragt vor dem Neustart
|
- EXE erkennt laufende Entwicklungsinstanz und fragt vor dem Neustart
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ Um das Programm zu starten: Doppelklick auf `Tätigkeitsnachweis-Generator.exe`
|
|||||||
## Bedienung
|
## Bedienung
|
||||||
|
|
||||||
1. **Input-Datei wählen** – Dropdown zeigt alle `.xlsx`-Dateien aus dem `input/`-Ordner
|
1. **Input-Datei wählen** – Dropdown zeigt alle `.xlsx`-Dateien aus dem `input/`-Ordner
|
||||||
|
- Bei leerem Input-Ordner: „Input-Ordner öffnen“ öffnet den Explorer.
|
||||||
|
- Excel-Dateien können per Drag-and-drop hochgeladen werden. Sie werden in den
|
||||||
|
Input-Ordner kopiert; danach wird die Dateiliste automatisch neu eingelesen.
|
||||||
|
- Nach manuellem Kopieren im Explorer „Input-Ordner neu einlesen“ anklicken.
|
||||||
- Nach Auswahl wird die Datei sofort validiert
|
- Nach Auswahl wird die Datei sofort validiert
|
||||||
- Angezeigt werden: Anzahl Mitarbeiter, Antragsnummern, Einträge pro Monat
|
- Angezeigt werden: Anzahl Mitarbeiter, Antragsnummern, Einträge pro Monat
|
||||||
2. **Template wählen** – Dropdown zeigt alle `.xlsx`-Dateien aus dem `template/`-Ordner
|
2. **Template wählen** – Dropdown zeigt alle `.xlsx`-Dateien aus dem `template/`-Ordner
|
||||||
|
|||||||
+64
-1
@@ -32,6 +32,14 @@ from src.writer import generate_activity_reports
|
|||||||
from version_check import UPDATE_DIR, get_latest_version
|
from version_check import UPDATE_DIR, get_latest_version
|
||||||
|
|
||||||
|
|
||||||
|
def open_input_folder(directory: Path):
|
||||||
|
directory.mkdir(parents=True, exist_ok=True)
|
||||||
|
if sys.platform == "win32":
|
||||||
|
os.startfile(str(directory))
|
||||||
|
else:
|
||||||
|
subprocess.run(["open" if sys.platform == "darwin" else "xdg-open", str(directory)], check=True)
|
||||||
|
|
||||||
|
|
||||||
def set_active_employee(employee_name: str):
|
def set_active_employee(employee_name: str):
|
||||||
"""Merkt die zuletzt angeklickte Person für die Monatsliste."""
|
"""Merkt die zuletzt angeklickte Person für die Monatsliste."""
|
||||||
st.session_state.active_month_employee = employee_name
|
st.session_state.active_month_employee = employee_name
|
||||||
@@ -155,9 +163,64 @@ col1, col2 = st.columns(2)
|
|||||||
with col1:
|
with col1:
|
||||||
st.subheader("1. Input-Datei")
|
st.subheader("1. Input-Datei")
|
||||||
input_files = get_available_input_files(app_config)
|
input_files = get_available_input_files(app_config)
|
||||||
|
for message in st.session_state.pop("input_upload_messages", []):
|
||||||
|
st.success(message)
|
||||||
|
for message in st.session_state.pop("input_upload_errors", []):
|
||||||
|
st.error(message)
|
||||||
if not input_files:
|
if not input_files:
|
||||||
st.warning("Keine .xlsx-Dateien im input/-Ordner gefunden.")
|
with st.container(border=True, key="input_file_panel"):
|
||||||
|
st.markdown("**Excel-Datei hinzufügen**")
|
||||||
|
st.caption("Keine .xlsx-Dateien im Input/-Ordner gefunden.")
|
||||||
|
input_directory = Path(app_config.input_dir)
|
||||||
|
uploaded_files = st.file_uploader(
|
||||||
|
"Excel-Dateien hierher ziehen oder auswählen",
|
||||||
|
type=["xlsx"], accept_multiple_files=True,
|
||||||
|
key=f"input_upload_{st.session_state.get('input_upload_generation', 0)}",
|
||||||
|
label_visibility="collapsed",
|
||||||
|
)
|
||||||
|
if uploaded_files:
|
||||||
|
saved, errors = [], []
|
||||||
|
for uploaded_file in uploaded_files:
|
||||||
|
try:
|
||||||
|
name = uploaded_file.name
|
||||||
|
if (Path(name).name != name or "/" in name or "\\" in name
|
||||||
|
or Path(name).suffix.lower() != ".xlsx" or name.startswith("~")):
|
||||||
|
raise ValueError("Bitte eine .xlsx-Datei mit gültigem Dateinamen auswählen.")
|
||||||
|
input_directory.mkdir(parents=True, exist_ok=True)
|
||||||
|
destination = input_directory / name
|
||||||
|
counter = 1
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
with destination.open("xb") as output:
|
||||||
|
output.write(uploaded_file.getbuffer())
|
||||||
|
break
|
||||||
|
except FileExistsError:
|
||||||
|
counter += 1
|
||||||
|
destination = input_directory / f"{Path(name).stem} ({counter}).xlsx"
|
||||||
|
saved.append(f"{destination.name} wurde in den Input-Ordner kopiert.")
|
||||||
|
except (OSError, ValueError) as exc:
|
||||||
|
errors.append(f"{uploaded_file.name} konnte nicht übernommen werden: {exc}")
|
||||||
|
st.session_state.input_upload_messages = saved
|
||||||
|
st.session_state.input_upload_errors = errors
|
||||||
|
st.session_state.input_upload_generation = st.session_state.get("input_upload_generation", 0) + 1
|
||||||
|
st.session_state.last_input_file = None
|
||||||
|
st.rerun()
|
||||||
|
st.caption("Dateien hierher ziehen oder auswählen. Sie werden automatisch im Input-Ordner gespeichert.")
|
||||||
|
folder_action, refresh_action = st.columns(2)
|
||||||
|
with folder_action:
|
||||||
|
if st.button("Ordner öffnen", icon="📁", key="open_input_directory", use_container_width=True):
|
||||||
|
try:
|
||||||
|
open_input_folder(input_directory)
|
||||||
|
except (OSError, subprocess.SubprocessError) as exc:
|
||||||
|
st.error(f"Der Input-Ordner konnte nicht geöffnet werden: {exc}")
|
||||||
|
with refresh_action:
|
||||||
|
if st.button("Neu einlesen", icon="🔄", key="refresh_input_directory", use_container_width=True,
|
||||||
|
help="Dateiliste aktualisieren, nachdem Dateien im Explorer hinzugefügt wurden."):
|
||||||
|
st.rerun()
|
||||||
selected_input = None
|
selected_input = None
|
||||||
|
st.session_state.parsed_records = []
|
||||||
|
st.session_state.input_validated = False
|
||||||
|
st.session_state.last_input_file = None
|
||||||
else:
|
else:
|
||||||
# Bei nur einer Datei: automatisch selektieren (keine Leerauswahl)
|
# Bei nur einer Datei: automatisch selektieren (keine Leerauswahl)
|
||||||
if len(input_files) == 1:
|
if len(input_files) == 1:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.3.2
|
1.3.3
|
||||||
Reference in new issue
Block a user