You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
3.1 KiB
84 lines
3.1 KiB
"""Search tab for the parliamentary explorer."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pandas as pd
|
|
|
|
import analysis.explorer_data as explorer_data
|
|
from analysis.tabs._rendering import _render_voting_results, st
|
|
|
|
|
|
def build_search_tab(db_path: str, show_rejected: bool) -> None:
|
|
"""Build the Motie Zoeken tab."""
|
|
st.subheader("Motie Zoeken")
|
|
|
|
df = explorer_data.load_motions_df(db_path)
|
|
if df.empty:
|
|
st.warning("Geen moties beschikbaar.")
|
|
return
|
|
|
|
if not show_rejected:
|
|
df = df[df["title"].fillna("").str.strip() != "Verworpen."]
|
|
|
|
col1, col2, col3 = st.columns([2, 1, 1])
|
|
with col1:
|
|
query = st.text_input(
|
|
"Zoek op titel", placeholder="bijv. stikstof, klimaat, wonen"
|
|
)
|
|
with col2:
|
|
years = sorted(df["year"].dropna().astype(int).unique().tolist())
|
|
if years:
|
|
year_range = st.select_slider(
|
|
"Jaar", options=years, value=(years[0], years[-1])
|
|
)
|
|
else:
|
|
year_range = (2019, 2024)
|
|
with col3:
|
|
min_controversy = st.slider(
|
|
"Min. controverse", min_value=0.0, max_value=1.0, value=0.0, step=0.05
|
|
)
|
|
|
|
working = df.copy()
|
|
working = working[
|
|
(working["year"] >= year_range[0]) & (working["year"] <= year_range[1])
|
|
]
|
|
if min_controversy > 0:
|
|
working = working[working["controversy_score"] >= min_controversy]
|
|
if query:
|
|
q = query.lower()
|
|
mask = working["title"].fillna("").str.lower().str.contains(q, regex=False)
|
|
working = working[mask]
|
|
|
|
working = working.sort_values(by="controversy_score", ascending=False)
|
|
st.caption(f"{len(working)} resultaten (top 50 getoond)")
|
|
|
|
for _, row in working.head(50).iterrows():
|
|
title = row.get("title") or f"Motie #{row['id']}"
|
|
date_str = row["date"].strftime("%d %b %Y") if pd.notna(row["date"]) else "?"
|
|
controversy = row.get("controversy_score") or 0
|
|
with st.expander(f"**{title}** — {date_str} — {controversy:.2f}"):
|
|
cols = st.columns(3)
|
|
cols[0].metric("Controverse", f"{controversy:.2f}")
|
|
cols[1].metric("Marge", f"{row.get('winning_margin', 0):.2f}")
|
|
cols[2].metric("Jaar", int(row["year"]) if pd.notna(row["year"]) else "?")
|
|
|
|
_render_voting_results(row.get("voting_results"))
|
|
|
|
url = row.get("url")
|
|
if url and str(url).startswith("http"):
|
|
st.markdown(f"[Bekijk op Tweede Kamer]({url})")
|
|
|
|
sim = explorer_data.query_similar(db_path, int(row["id"]), top_k=5)
|
|
if not sim.empty:
|
|
st.markdown("**Vergelijkbare moties:**")
|
|
for _, s in sim.iterrows():
|
|
s_date = (
|
|
pd.to_datetime(s["date"]).strftime("%Y")
|
|
if pd.notna(s.get("date"))
|
|
else ""
|
|
)
|
|
st.markdown(
|
|
f"- {s.get('title', 'Onbekend')} *(score: {s['score']:.3f}, {s_date})*"
|
|
)
|
|
else:
|
|
st.caption("_Nog geen vergelijkbare moties beschikbaar_")
|
|
|