diff --git a/app.py b/app.py
index 24ab722..c73f0a3 100644
--- a/app.py
+++ b/app.py
@@ -54,6 +54,15 @@ if "input_validated" not in st.session_state:
st.session_state.input_validated = False
if "template_validated" not in st.session_state:
st.session_state.template_validated = False
+# Caches für Validierung/Parsing – nur bei Dateiwechsel neu ausführen
+if "last_input_file" not in st.session_state:
+ st.session_state.last_input_file = None
+if "last_template_file" not in st.session_state:
+ st.session_state.last_template_file = None
+if "cached_val_result" not in st.session_state:
+ st.session_state.cached_val_result = None
+if "cached_tpl_result" not in st.session_state:
+ st.session_state.cached_tpl_result = None
# --- Layout: zwei Spalten ---
col1, col2 = st.columns(2)
@@ -73,9 +82,30 @@ with col1:
if selected_input:
input_path = Path(app_config.input_dir) / selected_input
- # Validiere und parse sofort
- with st.spinner("Validiere Input-Datei…"):
- val_result = validate_input_file(input_path, app_config.input_schema, app_config.month_sheet_pattern)
+
+ # Nur validieren/parsen wenn sich die Datei geändert hat
+ if selected_input != st.session_state.last_input_file:
+ with st.spinner("Validiere Input-Datei…"):
+ val_result = validate_input_file(input_path, app_config.input_schema, app_config.month_sheet_pattern)
+
+ if val_result.is_valid:
+ records = parse_input_file(
+ input_path,
+ app_config.input_schema,
+ app_config.month_sheet_pattern,
+ app_config.skip_empty_name,
+ app_config.skip_empty_antragsnummer,
+ )
+ st.session_state.parsed_records = records
+ st.session_state.input_validated = True
+ else:
+ st.session_state.parsed_records = []
+ st.session_state.input_validated = False
+
+ st.session_state.cached_val_result = val_result
+ st.session_state.last_input_file = selected_input
+ else:
+ val_result = st.session_state.cached_val_result
if not val_result.is_valid:
st.markdown(
@@ -100,27 +130,19 @@ with col1:
for warn in val_result.warnings:
st.warning(warn)
- # Parse die Datei
- records = parse_input_file(
- input_path,
- app_config.input_schema,
- app_config.month_sheet_pattern,
- app_config.skip_empty_name,
- app_config.skip_empty_antragsnummer,
- )
- st.session_state.parsed_records = records
- st.session_state.input_validated = True
-
- # Zeige Zusammenfassung
+ # Zeige Zusammenfassung aus gecachten Records
+ records = st.session_state.parsed_records
employees = get_unique_employees(records)
antragsnummern = get_unique_antragsnummern(records)
st.success(f"✅ {len(records)} Einträge in {val_result.info.get('sheets_with_data', 0)} Monats-Sheets")
- st.metric("Mitarbeiter", len(employees))
- st.metric("Antragsnummern", len(antragsnummern))
- with st.expander("Antragsnummern anzeigen"):
- for an in antragsnummern:
- st.text(f"• {an}")
+ pills = " ".join(
+ f'{an}'
+ for an in antragsnummern
+ )
+ st.markdown(f"**Antragsnummern:**
{pills}", unsafe_allow_html=True)
with col2:
st.subheader("2. Template")
@@ -140,9 +162,16 @@ with col2:
)
if selected_template:
- template_path = Path(app_config.template_dir) / selected_template
- with st.spinner("Validiere Template…"):
- tpl_result = validate_template(template_path, app_config.output_mapping)
+ # Nur validieren wenn sich das Template geändert hat
+ if selected_template != st.session_state.last_template_file:
+ template_path = Path(app_config.template_dir) / selected_template
+ with st.spinner("Validiere Template…"):
+ tpl_result = validate_template(template_path, app_config.output_mapping)
+ st.session_state.cached_tpl_result = tpl_result
+ st.session_state.last_template_file = selected_template
+ st.session_state.template_validated = tpl_result.is_valid
+ else:
+ tpl_result = st.session_state.cached_tpl_result
if not tpl_result.is_valid:
st.markdown(
@@ -176,11 +205,32 @@ st.subheader("3. Mitarbeiter auswählen")
if st.session_state.input_validated and st.session_state.parsed_records:
employees = get_unique_employees(st.session_state.parsed_records)
- selected_employees = st.multiselect(
- f"{len(employees)} Mitarbeiter gefunden – wähle aus, für wen Tätigkeitsnachweise erstellt werden sollen:",
- options=employees,
- default=employees,
+ st.caption(f"{len(employees)} Mitarbeiter gefunden – wähle aus, für wen Tätigkeitsnachweise erstellt werden sollen:")
+
+ # "Alle" / "Keine" Buttons
+ btn_col1, btn_col2 = st.columns(2)
+ if btn_col1.button("☑ Alle auswählen", use_container_width=True):
+ for emp in employees:
+ st.session_state[f"sel_{emp}"] = True
+ if btn_col2.button("☐ Keine auswählen", use_container_width=True):
+ for emp in employees:
+ st.session_state[f"sel_{emp}"] = False
+
+ # Mitarbeiter-Liste mit Rahmen
+ st.markdown(
+ '