diff --git a/app.py b/app.py
index 78d1cac..3fc5946 100644
--- a/app.py
+++ b/app.py
@@ -782,45 +782,71 @@ def page_history():
if st.session_state["selected_analysis_id"] not in valid_ids and records:
st.session_state["selected_analysis_id"] = records[0]["id"]
- st.write("### ๐ ๋ถ์ ์ด๋ ฅ ๋ชฉ๋ก")
- st.caption("๐ก ์๋ ๋ชฉ๋ก์์ **์ํ๋ ํ(๋ณด๊ณ ์ ์นด๋)**์ ๋๋ฅด์๋ฉด ํ๋จ์ ์์ธ ๋ถ์ ๋ด์ญ์ด ์ฆ์ ๊ฐฑ์ ๋ฉ๋๋ค.")
-
+ # ์ด๋ ฅ ํ
์ด๋ธ ๋ฐ์ดํฐ ํฌ๋งทํ
status_emoji = {"critical": "๐ด", "warning": "๐ก", "healthy": "๐ข"}
+ table_data = [{
+ "ID": r["id"],
+ "๋ถ์์ผ์": r["created_at"],
+ "์ํ": f"{status_emoji.get(r['overall_status'], '')} {r['overall_status']}",
+ "ํ์ผ๋ช
": r["filename"][:40],
+ "GPU ์": r["gpu_count"],
+ "XID": r["xid_count"],
+ "์ฌ๊ฐ": r["critical_count"],
+ "๊ฒฝ๊ณ ": r["warning_count"],
+ "๋๋ผ์ด๋ฒ": r["driver_version"],
+ "๋ฉ๋ชจ": (r.get("memo") or "")[:50],
+ } for r in records]
- # 1. ํ์ ๊ฐ ์ด ์ด๋ฆ(ํค๋) ๋ฐฐ์น (๊ฐ๋ก ๋น์จ ์นผ์ ๋ ฌ)
- h_col1, h_col2, h_col3 = st.columns([1.2, 1.0, 1.2])
- h_col1.markdown("**๐ข ์ํ & ๋ณด๊ณ ์ ํ์ผ๋ช
**")
- h_col2.markdown("**๐ ๋ถ์ ์ผ์**")
- h_col3.markdown("**๐ ์์ฝ ํต๊ณ (GPU / XID / RMA)**")
- st.markdown("
", unsafe_allow_html=True)
+ st.write("### ๐ ๋ถ์ ์ด๋ ฅ ํ
์ด๋ธ ๋ชฉ๋ก")
+ st.caption("๐ก ํ ์ผ์ชฝ ๋์ **๋๊ทธ๋ผ๋ฏธ ์ ํํญ๋ชฉ(๋ผ๋์ค ๋ฒํผ)**์ ํด๋ฆญํ์๊ฑฐ๋, ํ๋จ ๋๋กญ๋ค์ด์์ ๋ณด๊ณ ์๋ฅผ ์ ํํ์๋ฉด ์์ธ ๋ด์ญ์ด ํ์๋ฉ๋๋ค.")
- # 2. ์คํฌ๋กค ๊ฐ๋ฅํ ์ปจํ
์ด๋ ๋ด๋ถ์ ๋ผ๋์ค ๋ฒํผ์ด ์๋ ๊ฐ๋กํ ํต์ง ํด๋ฆญ ํ ๋ ๋๋ง
- with st.container(height=380):
- for r in records:
- emoji = status_emoji.get(r['overall_status'], '๐ข')
- is_selected = (r["id"] == st.session_state["selected_analysis_id"])
-
- # ํ ์ ์ฒด๋ฅผ ํ๋์ ๋์ฐํ ๋ฒํผ์ผ๋ก ๊ตฌ์ฑ (๋ง์ฐ์ค ํด๋ฆญ ์์ญ ๊ทน๋ํ)
- # ๋ผ๋ฒจ ํฌ๋งท: ์ํ์ด๋ชจ์ง | ํ์ผ๋ช
| ๋ถ์์ผ์ | ์์ฝํต๊ณ
- btn_label = (
- f"{emoji} [ID: {r['id']}] {r['filename'][:30]} | "
- f"๐ {r['created_at']} | "
- f"๐ฎ GPU {r['gpu_count']}๊ฐ / โ ๏ธ XID {r['xid_count']}๊ฑด / ๐ง RMA {r['rma_count']}๋"
- )
-
- # ๋ฒํผ ํด๋ฆญ ์ ํด๋น ๋ณด๊ณ ์ ID๋ก ์ธ์
์ํ๋ฅผ ์ ์ฅํ๊ณ ํ๋ฉด ๊ฐฑ์
- if st.button(
- btn_label,
- key=f"btn_row_{r['id']}",
- use_container_width=True,
- type="primary" if is_selected else "secondary"
- ):
- st.session_state["selected_analysis_id"] = r["id"]
- st.rerun()
+ # st.dataframe์ selection ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ๋ง์ฐ์ค ํ ์ ํ ๊ฐ์ง ๋ฐ Rerun ํธ๋ฆฌ๊ฑฐ
+ df_display = pd.DataFrame(table_data)
+ selection_event = st.dataframe(
+ df_display,
+ use_container_width=True,
+ hide_index=True,
+ selection_mode="single-row",
+ on_select="rerun",
+ key="history_table"
+ )
+
+ # ํ
์ด๋ธ์์ ๋ง์ฐ์ค ํด๋ฆญ์ผ๋ก ํ์ ์ ํํ์ ๋ ์ธ์
์ํ ID ๊ฐฑ์
+ selected_rows = selection_event.get("selection", {}).get("rows", [])
+ if selected_rows:
+ selected_row_idx = selected_rows[0]
+ if selected_row_idx < len(records):
+ st.session_state["selected_analysis_id"] = records[selected_row_idx]["id"]
# ์์ธ ์กฐํ
st.markdown("---")
+ st.subheader("๐ ์์ธ ์กฐํ")
+
+ # ๋ณด๊ณ ์ ์ ํ์ ๋๋ UI ๊ฐ์ : ๋๋กญ๋ค์ด ์ ํ๋ฐ์ค ์ ๊ณต
+ history_options = [
+ (r["id"], f"[ID: {r['id']}] {status_emoji.get(r['overall_status'], '')} {r['filename'][:30]} ({r['created_at']})")
+ for r in records
+ ]
+
+ # ํ์ฌ ์ ํ๋ ID์ ํด๋นํ๋ ์ต์
์ ์ธ๋ฑ์ค ์ฐพ๊ธฐ (์๋ฐฉํฅ ์ฐ๋์ฉ)
+ default_index = 0
+ for idx, opt in enumerate(history_options):
+ if opt[0] == st.session_state["selected_analysis_id"]:
+ default_index = idx
+ break
+
+ selected_option = st.selectbox(
+ "์กฐํํ ๋ณด๊ณ ์ ์ ํ",
+ options=history_options,
+ index=default_index,
+ format_func=lambda x: x[1]
+ )
+
+ if selected_option:
+ st.session_state["selected_analysis_id"] = selected_option[0]
+
selected_id = st.session_state["selected_analysis_id"]
+
detail = get_analysis_detail(selected_id)
if not detail: