This commit is contained in:
2026-05-12 10:17:56 +02:00
parent 6115523de9
commit b3ba440269
61 changed files with 132 additions and 0 deletions
+132
View File
@@ -0,0 +1,132 @@
"""
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ů")