""" create_report.py Streamlit report kontaktů z MySQL tabulky CTMS_contacts. Spuštění: streamlit run create_report.py """ from datetime import date import mysql.connector import pandas as pd import streamlit as st # ── Konfigurace ──────────────────────────────────────────────────────────────── DB_CONFIG = { "host": "192.168.1.76", "port": 3306, "user": "root", "password": "Vlado9674+", "database": "studie", "charset": "utf8mb4", } TABLE = "CTMS_contacts" DISPLAY_COLS = { "site_id": "Site ID", "institution_name": "Institution", "pi_full_name": "PI", "contact_title": "Title", "last_name": "Last Name", "first_name": "First Name", "contact_role": "Role", "primary_indicator": "Primary", "phone": "Phone", "phone_mobile": "Mobile", "email": "Email", "contact_start_date": "Start Date", "contact_end_date": "End Date", } # ── Data ─────────────────────────────────────────────────────────────────────── @st.cache_data(ttl=300) def load_data() -> pd.DataFrame: cols = ", ".join(DISPLAY_COLS.keys()) sql = ( f"SELECT protocol_id, file_date, {cols} " f"FROM {TABLE} " f"ORDER BY protocol_id, site_id, contact_role, last_name, first_name" ) conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor(dictionary=True) cursor.execute(sql) rows = cursor.fetchall() cursor.close() conn.close() return pd.DataFrame(rows) # ── Aplikace ─────────────────────────────────────────────────────────────────── st.set_page_config(page_title="CTMS Contacts", page_icon="🏥", layout="wide") st.title("🏥 CTMS Contacts — Czechia") try: df = load_data() except Exception as e: st.error(f"Chyba připojení k MySQL: {e}") st.stop() # ── Sidebar filtry ───────────────────────────────────────────────────────────── with st.sidebar: st.header("Filtry") protocols = ["Všechny"] + sorted(df["protocol_id"].unique().tolist()) sel_proto = st.selectbox("Protokol", protocols) roles = ["Všechny"] + sorted(df["contact_role"].dropna().unique().tolist()) sel_role = st.selectbox("Role", roles) sites = ["Všechny"] + sorted(df["site_id"].dropna().unique().tolist()) sel_site = st.selectbox("Site", sites) search = st.text_input("Hledat (jméno, email…)") st.divider() if st.button("🔄 Obnovit data"): st.cache_data.clear() st.rerun() st.caption(f"Naposledy načteno: {pd.Timestamp.now().strftime('%H:%M:%S')}") # ── Filtrování ───────────────────────────────────────────────────────────────── filtered = df.copy() if sel_proto != "Všechny": filtered = filtered[filtered["protocol_id"] == sel_proto] if sel_role != "Všechny": filtered = filtered[filtered["contact_role"] == sel_role] if sel_site != "Všechny": filtered = filtered[filtered["site_id"] == sel_site] if search: mask = filtered.apply( lambda row: row.astype(str).str.contains(search, case=False, na=False).any(), axis=1, ) filtered = filtered[mask] # ── Metriky ──────────────────────────────────────────────────────────────────── col1, col2, col3, col4 = st.columns(4) col1.metric("Kontaktů celkem", len(filtered)) col2.metric("Protokolů", filtered["protocol_id"].nunique()) col3.metric("Středisek", filtered["site_id"].nunique()) col4.metric("Rolí", filtered["contact_role"].nunique()) st.divider() # ── Tabulka ──────────────────────────────────────────────────────────────────── display = filtered[["protocol_id", "file_date"] + list(DISPLAY_COLS.keys())].copy() display = display.rename(columns={"protocol_id": "Protocol", "file_date": "File Date", **DISPLAY_COLS}) st.dataframe( display, width="stretch", hide_index=True, column_config={ "Email": st.column_config.LinkColumn("Email", display_text=".*"), "Start Date": st.column_config.DateColumn("Start Date", format="DD-MMM-YYYY"), "End Date": st.column_config.DateColumn("End Date", format="DD-MMM-YYYY"), }, ) st.caption(f"Zobrazeno {len(filtered)} z {len(df)} záznamů")