diff --git a/app/app_db/app.db b/app/app_db/app.db index 51b0afe..87d9f11 100644 Binary files a/app/app_db/app.db and b/app/app_db/app.db differ diff --git a/app/data/parquet_store.py b/app/data/parquet_store.py new file mode 100644 index 0000000..e69de29 diff --git a/app/pages/costobjects.py b/app/pages/costobjects.py index 6c8f40a..624e950 100644 --- a/app/pages/costobjects.py +++ b/app/pages/costobjects.py @@ -1,11 +1,13 @@ import streamlit as st import pandas as pd -from data.scriptloader import get_sql +#from data.scriptloader import get_sql from data.db import load_data from auth_runtime import require_login -from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out -from auth import get_fullname_for_user +#from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out +#from auth import get_fullname_for_user import numpy as np +from tools.excel_export import df_to_excel_bytes +from tools.help_text import get_help st.set_page_config(page_title="Co-App Home", page_icon="🏠", layout="wide") @@ -13,7 +15,17 @@ st.set_page_config(page_title="Co-App Home", page_icon="🏠", layout="wide") authenticator = require_login() st.session_state["authenticator"] = authenticator +st.markdown(""" + +""", unsafe_allow_html=True) +description = get_help("costobjects") +with st.expander(label="ℹ️ Hilfe / Hinweise", expanded=False): # ❓ + st.markdown(description) @st.cache_data def cache_data() -> pd.DataFrame: @@ -38,19 +50,32 @@ def sidebar_filters(df) -> dict: This function should contain UI concerns only (widgets, layout), and not data filtering logic, to keep the code maintainable. """ + + st.markdown(""" + + """, unsafe_allow_html=True) + st.sidebar.header("Filter") if st.sidebar.button("Refresh (Global)"): cache_data.clear() st.rerun() - year = st.sidebar.selectbox(label="Jahr", options=(2025, 2026), index=1) filter_text = st.sidebar.text_input(label="Textsuche", placeholder="Suche Objekt, Text, Verantwortlicher") col_s1, col_s2 = st.sidebar.columns(2) with col_s1: - typ = st.sidebar.selectbox(label="Typ", options=sorted(df["typ"].dropna().unique()), index=1) + year = st.selectbox(label="Jahr", options=(2025, 2026), index=1) with col_s2: - obj = st.sidebar.multiselect("obj", sorted(df["obj"].dropna().unique())) + typ = st.selectbox(label="Typ", options=sorted(df["typ"].dropna().unique()), index=1) + obj = st.sidebar.multiselect("obj", sorted(df["obj"].dropna().unique())) zgrp1 = st.sidebar.multiselect("ZGrp1", sorted(df["zgrp1"].dropna().unique())) zgrp2 = st.sidebar.multiselect("ZGrp2", sorted(df["zgrp2"].dropna().unique())) zgrp3 = st.sidebar.multiselect("ZGrp3", sorted(df["zgrp3"].dropna().unique())) @@ -100,9 +125,14 @@ def render_table(df): Keep this function presentation-only: it should not modify data. """ + st.markdown("### Übersicht Kostenobjekte") st.dataframe(df, hide_index=True, width="stretch", height="stretch") +def download_data(df): + df.to_excel(path) + + def page(): """ Page entry point: orchestrates data loading, UI, filtering, and rendering. @@ -129,10 +159,9 @@ def page(): # ----------------------------- # Presentation # ----------------------------- - - df = df.sort_values(by="obj", key=lambda s: pd.to_numeric(s, errors="coerce")) df_clean = df[df.columns[:-1]] # letzte Spalten entfernen (sysdate) df_display = df_clean.loc[mask] + df_display = df_display.sort_values(by="obj", key=lambda s: pd.to_numeric(s, errors="coerce")) render_table(df_display) col1, col2 = st.columns(2) @@ -141,11 +170,15 @@ def page(): with col1: st.text(f"Datenstand: {data_as_of}") - st.text("Datenquelle: Oracle (PENTA)") with col2: st.markdown(f"