clea up code and layout

This commit is contained in:
knedlik
2025-12-10 22:52:22 +01:00
parent 7f21716358
commit e2091ec677
11 changed files with 211 additions and 86 deletions

View File

@@ -1,2 +1,3 @@
[client]
showSidebarNavigation = false
toolbarMode = "minimal"

21
app/.streamlit/style.css Normal file
View File

@@ -0,0 +1,21 @@
/* Footer entfernen */
footer {visibility: hidden !important;}
div[data-testid="stStatusWidget"] {display: none !important;}
/* Sidebar-Spacing kompakter */
section[data-testid="stSidebar"] > div {
padding-top: 0.5rem !important;
}
/* Haupt-Container kompakter */
.block-container {
padding-top: 0.6rem !important;
padding-bottom: 0.6rem !important;
}
/* Widgets enger */
.stButton, .stTextInput, .stSelectbox {
margin-bottom: 0.3rem !important;
}

View File

@@ -3,8 +3,30 @@ import yaml
from yaml.loader import SafeLoader
import streamlit_authenticator as stauth
from streamlit_authenticator.utilities.exceptions import LoginError
from auth import (
load_credentials_from_db,
needs_password_change,
update_password,
get_role_for_user,
get_fullname_for_user,
get_sidebar
)
st.markdown("""
<style>
/* Streamlit Hamburger-Menü ausblenden */
div[data-testid="stToolbar"] {
visibility: hidden !important;
}
/* Optional: ganz entfernen statt nur unsichtbar machen */
div[data-testid="stDecoration"] {
display: none !important;
}
</style>
""", unsafe_allow_html=True)
from auth import load_credentials_from_db, needs_password_change, update_password
def get_authenticator():
with open("config/auth.yaml", "r", encoding="utf-8") as f:
@@ -41,8 +63,23 @@ def require_login():
st.warning("Bitte Benutzername und Passwort eingeben.")
st.stop()
# Passwortwechsel erzwingen
#--------------------------------------------------------------------------------------
# Ab hier bin ich eingeloggt
#--------------------------------------------------------------------------------------
username = st.session_state.get("username")
if "df_sidebar" not in st.session_state:
role_text = get_role_for_user(username)
fullname = get_fullname_for_user(username)
sidebar = get_sidebar(role_text, username)
st.session_state["role_text"] = role_text
st.session_state["fullname"] = fullname
st.session_state["df_sidebar"] = sidebar
# Passwortwechsel erzwingen
if needs_password_change(username):
st.warning("Du musst dein Passwort ändern, bevor du die Anwendung nutzen kannst.")

View File

@@ -7,17 +7,24 @@ from auth_runtime import require_login
from ui.sidebar import build_sidebar
import os
from app_db.app_db import get_list
from pathlib import Path
from tools.load_css import load_css
APP_ENV = os.environ.get("APP_ENV", "dev")
logger = setup_logging(APP_ENV)
logger = logging.getLogger(__name__)
load_css()
def main():
st.set_page_config(
page_title=f"Co-App Home - V{__version__}",
page_icon="🔒",
layout="centered",
menu_items=None,
)
authenticator = require_login()
@@ -32,7 +39,6 @@ def main():
st.session_state["authenticator"] = authenticator
# ... dann ist der name des users in der sesstion_state verfügbar!
# Ich suche mir erst mal alles zusammen, was ich dann in session_state speichern will ...
username = st.session_state.get("name") # wird duch authenticator gesetzt
role_text = get_role_for_user(username)

View File

@@ -6,7 +6,7 @@ from auth_runtime import require_login
from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out
from auth import get_fullname_for_user
hide_sidebar_if_logged_out()
# hide_sidebar_if_logged_out()
st.set_page_config(page_title="Co-App Home", page_icon="🏠")

View File

@@ -1,18 +1,31 @@
import streamlit as st
from auth_runtime import require_login
from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out
from ui.sidebar import build_sidebar
from auth import get_fullname_for_user
import pandas as pd
from numpy.random import default_rng as rng
from tools.load_css import load_css
hide_sidebar_if_logged_out()
load_css()
st.set_page_config(page_title="Co-App Home", page_icon="🏠")
authenticator = require_login()
st.session_state["authenticator"] = authenticator
build_sidebar()
#build_sidebar()
username = st.session_state.get("username")
def home():
username = st.session_state.get("name")
st.header("Controlling-Portal")
st.info(f"Willkommen, {get_fullname_for_user(username)}!")
st.markdown("**Hier könnte eine Hinweistext für den Benutzer stehen**")
df = pd.DataFrame(rng(0).standard_normal((20, 3)), columns=["a", "b", "c"])
st.area_chart(df)
if __name__ == "__main__":
home()

View File

@@ -1,52 +1,115 @@
import streamlit as st
from auth_runtime import require_login
from ui.sidebar import hide_sidebar_if_logged_out
from ui.sidebar import build_sidebar
from auth import create_user
from pathlib import Path
from tools.check_permission import check
from tools.load_css import load_css
DASH_NAME = Path(__file__).stem # Hier muss die dash_id aus der DB stehen -> wird gegen die session_state geprüft (User-Berechtigung)
hide_sidebar_if_logged_out()
load_css()
st.set_page_config(page_title="Co-App Benutzer", page_icon="🏠")
authenticator = require_login()
username = st.session_state.get("username")
df = st.session_state.get("df_sidebar")
st.session_state["authenticator"] = authenticator
if check(df,DASH_NAME) == False:
st.markdown("**FEHLER**")
st.error("Die Seite kann nicht angezeigt werden - keine Berechtigung!")
st.stop()
def sidebar():
st.title("Benutzerverwaltung")
fullname = st.session_state.get("fullname")
role_text = st.session_state.get("role_text")
with st.expander("Neuen Nutzer anlegen"):
new_u = st.text_input("Neuer Username", key="new_u")
new_fname = st.text_input("Vorname", key="new_fname")
new_lname = st.text_input("Nachname", key="new_lname")
new_email = st.text_input("E-Mail", key="new_email")
new_p = st.text_input("Neues Passwort", type="password", key="new_p")
new_role = st.selectbox("Rolle", ["user", "admin"], key="new_role")
with st.sidebar:
st.logo("app/images/GMN_Logo_neu_rgb.png", size="small")
st.markdown(f"**{fullname}** ({role_text})")
col1, col2, col3 = st.columns([2,2,1])
# with col1:
if st.button("Anlegen"):
if new_u and new_p:
ok = create_user(
new_u.strip(),
new_p,
new_role,
new_email.strip() or None,
new_fname.strip() or None,
new_lname.strip() or None,
)
st.success("Nutzer angelegt.") if ok else st.error(
"Username bereits vorhanden oder Fehler."
)
else:
st.warning("Bitte Username und Passwort eingeben.")
# if st.button("Logout", use_container_width=True):
# st.rerun()
with col1:
st.subheader("Dein Bereich")
st.write(f"Personalisierter Content für **{username}**.")
authenticator.logout("Logout")
# st.rerun()
# if st.button("Home", use_container_width=True):
# st.switch_page("pages/home.py")
with col2:
if st.button("🏠 Home", use_container_width=True):
st.switch_page("pages/home.py")
user()
def user():
st.header("Benutzerverwaltung")
if __name__ == "__main__":
sidebar()
# username = st.session_state.get("username")
# df = st.session_state.get("df_sidebar")
# if check(df,DASH_NAME) == False:
# st.markdown("**FEHLER**")
# st.error("Die Seite kann nicht angezeigt werden - keine Berechtigung!")
# st.stop()
# df = st.session_state.get("df_sidebar")
# st.text(DASH_NAME)
# st.text(st.session_state.get(username))
# print(df)
# st.title("Benutzerverwaltung")
# with st.expander("Neuen Nutzer anlegen"):
# new_u = st.text_input("Neuer Username", key="new_u")
# new_fname = st.text_input("Vorname", key="new_fname")
# new_lname = st.text_input("Nachname", key="new_lname")
# new_email = st.text_input("E-Mail", key="new_email")
# new_p = st.text_input("Neues Passwort", type="password", key="new_p")
# new_role = st.selectbox("Rolle", ["user", "admin"], key="new_role")
# if st.button("Anlegen"):
# if new_u and new_p:
# ok = create_user(
# new_u.strip(),
# new_p,
# new_role,
# new_email.strip() or None,
# new_fname.strip() or None,
# new_lname.strip() or None,
# )
# st.success("Nutzer angelegt.") if ok else st.error(
# "Username bereits vorhanden oder Fehler."
# )
# else:
# st.warning("Bitte Username und Passwort eingeben.")
# st.subheader("Dein Bereich")
# st.write(f"Personalisierter Content für **{username}**.")

View File

View File

@@ -1,27 +0,0 @@
import streamlit as st
from auth_runtime import require_login
from auth import get_sidebar, get_fullname_for_user, get_role_for_user
def check(df, page_name):
if "df_sidebar" not in st.session_state:
# authenticator = require_login()
username = st.session_state.get("username")
role_text = get_role_for_user(username)
fullname = get_fullname_for_user(username)
df = get_sidebar(role_text, username)
st.session_state["role_text"] = role_text
st.session_state["fullname"] = fullname
st.session_state["df_sidebar"] = df
if df is None or df.empty:
return False # oder True je nach gewünschtem Verhalten
allowed = not df[
(df["dash_type"] == "page") &
(df["page_file"] == page_name)
].empty
return True

8
app/tools/load_css.py Normal file
View File

@@ -0,0 +1,8 @@
import streamlit as st
from pathlib import Path
def load_css():
css_path = Path(__file__).parent.parent / ".streamlit" / "style.css"
if css_path.exists():
st.markdown(f"<style>{css_path.read_text()}</style>", unsafe_allow_html=True)

View File

@@ -7,8 +7,8 @@ from app_db.app_db import get_conn, get_list
def build_sidebar():
if st.session_state.get("authentication_status") != True:
return
# if st.session_state.get("authentication_status") != True:
# return
authenticator = st.session_state.get("authenticator")
username = st.session_state.get("name")
@@ -21,19 +21,18 @@ def build_sidebar():
df = st.session_state.get("df_sidebar")
with st.sidebar:
st.logo("app/images/GMN_Logo_neu_rgb.png", size="small")
st.markdown(f"**{fullname}** ({role_text})")
col1, col2, col3 = st.columns([2,2,1])
col1, col2 = st.columns(2)
with col1:
if st.button("Logout", use_container_width=True):
authenticator.logout("Logout", "unrendered")
st.rerun()
authenticator.logout("Logout")
with col2:
if st.button("Home", use_container_width=True):
st.switch_page("pages/home.py")
st.divider()
st.markdown("## Menü")
# --- Suchfeld ---
query = st.text_input("Menü-Suche", "", placeholder="z.B. Umsatz, Kosten, User ...")
@@ -42,6 +41,9 @@ def build_sidebar():
# Aktive Seite ermitteln (für Expander-Status / Highlight)
current_page = st.session_state.get("_page_path")
# --- DF filtern, falls Suchbegriff gesetzt ---
if query:
mask = (
@@ -56,6 +58,7 @@ def build_sidebar():
st.info("Keine Einträge zum Suchbegriff gefunden.")
return
# --- Gruppiert durchlaufen ---
for group_text, df_group in df_view.groupby("group_text"):
# Expander offen, wenn: