From 13385db5efb01123964545cf062678eee471037b Mon Sep 17 00:00:00 2001 From: hansi Date: Mon, 22 Dec 2025 08:21:04 +0100 Subject: [PATCH] Add dashboard management --- app/pages/dashboards.py | 275 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) diff --git a/app/pages/dashboards.py b/app/pages/dashboards.py index e69de29..5f51d91 100644 --- a/app/pages/dashboards.py +++ b/app/pages/dashboards.py @@ -0,0 +1,275 @@ +import streamlit as st +from auth_runtime import require_login +# from ui.sidebar import build_sidebar +from auth import create_user +from pathlib import Path +from tools.load_css import load_css +from app_db.app_db import get_list, send_cmd +from ui.selectboxes import get_roles, get_id +import bcrypt + + +DASH_NAME = Path(__file__).stem # Hier muss die dash_id aus der DB stehen -> wird gegen die session_state geprüft (User-Berechtigung) + +load_css() + +st.set_page_config(page_title="Co-App Benutzer", page_icon=":material/person:", layout="wide", initial_sidebar_state="collapsed") + +authenticator = require_login() +st.session_state["authenticator"] = authenticator + + + + +def sidebar(): + + fullname = st.session_state.get("fullname") + role_text = st.session_state.get("role_text") + + with st.sidebar: + + st.logo("app/images/GMN_Logo_neu_rgb.png", size="small") + st.markdown(f"**{fullname}** ({role_text})") + + col1, col2 = st.columns([2,2]) + with col1: + authenticator.logout("Logout") + with col2: + if st.button("Home", use_container_width=True, icon=":material/home:"): + st.switch_page("pages/home.py") + + user() + + +@st.dialog("Dashboard anlegen") +def dialog_create_dashboard(): + txt_username = st.text_input("Benutzername") + txt_firstname = st.text_input("Vorname") + txt_lastname = st.text_input("Nachname") + txt_email = st.text_input("Email") + txt_pwd = st.text_input("Kennwort", type="password") + cmb_role = st.selectbox("Rolle", get_roles(), index=None) + if st.button("Save"): + if create_user( + username=txt_username, + firstname=txt_firstname, + lastname=txt_lastname, + email=txt_email, + role_id=get_id(cmb_role), + password=txt_pwd + ): + st.session_state.save_msg = f"✅ Benutzer '{txt_username}' erfolgreich gespeichert" + else: + st.session_state.save_msg = "❌ Fehler beim Speichern" + st.rerun() + + +@st.dialog("Dashboard löschen") +def dialog_delete_dashboard(id): + if id == None: + st.write("kein Benutzer ausgewählt") + else: + df = get_list("select username from users where id = ?",(id,)) + username = df.iloc[0]["username"] + st.write(f"Der Benutzer {username} wird gelöscht! Sind Sie sicher?") + if st.button("Löschen"): + if username != "admin": + if send_cmd("delete from users where id = ?",(id,)): + st.session_state.delete_msg = f"✅ Benutzer '{username}' erfolgreich gelöscht!" + else: + st.session_state.delete_msg = f"❌ Benutzer '{username}' konnte nicht gelöscht werden!" + else: + st.session_state.delete_msg = f"❌ Benutzer '{username}' darf nicht gelöscht werden!" + st.rerun() + + +@st.dialog("Dashboard bearbeiten") +def dialog_edit_dashboard(id): + if id == None: + st.write("kein Benutzer ausgewählt") + else: + sql = """ + select + u.id, + u.username as user, -- ACHTUNG: nicht mit username arbeiten, da Überschneidung in sessionstate!! + u.firstname, + u.lastname, + u.email, + u.role_id || ' | ' || r.role_text as role, + r.role_text, + u.new_pwd, + u.active + from + users u + left join roles r + on u.role_id = r.role_id + where u.id = ? + """ + df = get_list(sql,(id,)) + + + # df = get_list("select username from users where id = ?",(id,)) + + # st.session_state.orig_user_data = df + + + df_roles = get_roles() + roles = df_roles["text"].tolist() + role = df.iloc[0]["role"] + try: + idx = roles.index(role) + except: + idx = None + col1, col2 = st.columns([2,1],vertical_alignment="center") + with col1: + txt_username = st.text_input(label="Benutzername", value=df.iloc[0]["user"]) + with col2: + is_active = st.checkbox(label="Aktiv", value=df.iloc[0]["active"]) + txt_firstname = st.text_input(label="Vorname", value=df.iloc[0]["firstname"]) + txt_lastname = st.text_input(label="Nachname", value=df.iloc[0]["lastname"]) + txt_email = st.text_input(label="Email", value=df.iloc[0]["email"]) + txt_pwd = st.text_input(label="Passwort", placeholder="Neues Passwort eingeben", type="password") + new_pwd = st.checkbox(label="Neues Passwort", value=df.iloc[0]["new_pwd"]) + cmb_role = st.selectbox(label="Rolle", options=roles, placeholder="Rolle auswählen", index=idx) + + + if st.button("Save"): + pw_hash = bcrypt.hashpw(txt_pwd.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") + + if txt_pwd and txt_pwd.strip(): + sql = """ + update users set + username = ?, + active = ?, + firstname = ?, + lastname = ?, + email = ?, + password_hash = ?, + new_pwd = ?, + role_id = ? + where id = ? + """ + params = (txt_username, is_active, txt_firstname, txt_lastname, txt_email, pw_hash, new_pwd, get_id(cmb_role), id) + # send_cmd(sql,(txt_username, txt_firstname, txt_lastname, txt_email, pw_hash, new_pwd, get_id(cmb_role), id)) + else: + sql = """ + update users set + username = ?, + active = ?, + firstname = ?, + lastname = ?, + email = ?, + new_pwd = ?, + role_id = ? + where id = ? + """ + params = (txt_username, is_active, txt_firstname, txt_lastname, txt_email, new_pwd, get_id(cmb_role), id) + # send_cmd(sql,(txt_username, txt_firstname, txt_lastname, txt_email, new_pwd, get_id(cmb_role), id)) + print (params) + if send_cmd(sql, params): + st.session_state.save_msg = f"✅ Benutzer '{txt_username}' erfolgreich geändert" + else: + st.session_state.save_msg = "❌ Fehler beim Speichern" + st.rerun() + + + +def dashborad(): + + if "selected_dashid" not in st.session_state: + st.session_state.selected_dash_id = None + + # tab_user, tab_role, tab_permission = st.tabs(["Benutzer", "Rollen", "Berechtigungen"]) + + #-------------------------------------------------------------------------------------------------- + # Dashboard-Verwaltung + #-------------------------------------------------------------------------------------------------- + + # with tab_user: + + + + df = get_list(""" + select + u.id, + u.username, + u.firstname, + u.lastname, + u.role_id || ' | ' || r.role_text as role, + u.new_pwd, + u.active + from + users u + left join roles r + on u.role_id = r.role_id + """) + + + + col_find_dashboard col_create_dashboard, col_edit_dashboard, col_delete_user = st.columns([3,2,2,2], vertical_alignment="bottom") + + with col_find_user: + txt_search = st.text_input(label="Suche", label_visibility="hidden", placeholder="Benutzer, Vorname, ...", icon=":material/search:") + + with col_create_user: + if st.button(label="Benutzer anlegen", use_container_width=True, icon=":material/person_add:"): + dialog_create_user() + if "save_msg" in st.session_state: + st.toast(st.session_state.save_msg) + del st.session_state.save_msg + + with col_edit_user: + if st.button(label="Benutzer bearbeiten", use_container_width=True, icon=":material/person_edit:"): + if not st.session_state.selected_user_id is None: + dialog_edit_user(st.session_state.selected_user_id) + else: + st.toast("❌ Bitte erst eine Zeile auswählen") + if "save_msg" in st.session_state: + st.toast(st.session_state.save_msg) + del st.session_state.save_msg + + with col_delete_user: + if st.button(label="Benutzer löschen", use_container_width=True, icon=":material/person_remove:"): + if not st.session_state.selected_user_id is None: + dialog_delete_user(st.session_state.selected_user_id) + else: + st.toast("❌ Bitte erst eine Zeile auswählen") + if "delete_msg" in st.session_state: + st.toast(st.session_state.delete_msg) + del st.session_state.delete_msg + + + + + if txt_search.strip(): + txt_search_norm = txt_search.strip().lower() + mask = ( + df["username"].fillna("").str.lower().str.contains(txt_search_norm) + | df["firstname"].fillna("").str.lower().str.contains(txt_search_norm) + | df["lastname"].fillna("").str.lower().str.contains(txt_search_norm) + ) + df_view = df.loc[mask].copy() + else: + df_view = df.copy() + + event = st.dataframe(df_view,key="data", on_select="rerun", selection_mode="single-row") + rows = event.selection.rows + if rows: + row_idx = rows[0] + st.session_state.selected_user_id = int(df_view.iloc[row_idx]["id"]) + else: + st.session_state.selected_user_id = None + + + +if __name__ == "__main__": + sidebar() + + + + + + + + +