z230
This commit is contained in:
@@ -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ů")
|
||||
Reference in New Issue
Block a user