input Validierung und UI handling fühlbar beschleunigt
This commit is contained in:
1 parent
31cdc7747f
commit
f4afd4b2e5
1 file changed
+77
-27
@@ -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'<span style="display:inline-block; background:#e8f0fe; color:#1a73e8; '
|
||||
f'border-radius:16px; padding:4px 12px; margin:3px; font-size:0.9em; '
|
||||
f'white-space:nowrap">{an}</span>'
|
||||
for an in antragsnummern
|
||||
)
|
||||
st.markdown(f"**Antragsnummern:**<br>{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(
|
||||
'<div style="border:1px solid #d5d5d5; border-radius:6px; padding:8px 12px; '
|
||||
'background:#fafafa; max-height:300px; overflow-y:auto">',
|
||||
unsafe_allow_html=True,
|
||||
)
|
||||
selected_employees = []
|
||||
for emp in employees:
|
||||
key = f"sel_{emp}"
|
||||
if key not in st.session_state:
|
||||
st.session_state[key] = True
|
||||
if st.checkbox(emp, value=st.session_state[key], key=key):
|
||||
selected_employees.append(emp)
|
||||
st.markdown("</div>", unsafe_allow_html=True)
|
||||
|
||||
st.caption(f"{len(selected_employees)} von {len(employees)} Mitarbeitern ausgewählt")
|
||||
else:
|
||||
selected_employees = []
|
||||
|
||||
Reference in new issue
Block a user