Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions frontend/components/risk_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,14 @@ def render_response_execution(
if "resp_active_event_sel" not in st.session_state:
st.session_state["resp_active_event_sel"] = 0

if "active_risk_event_id" in st.session_state:
target_id = st.session_state["active_risk_event_id"]
if target_id in event_ids:
new_idx = event_ids.index(target_id)
# 🧪 關鍵修正:若有外部跳轉指令,手動強制覆寫 selectbox 的內部 state
st.session_state["resp_active_event_sel"] = new_idx
# 外部跳轉(卡片「查看分析」)是一次性指令:取出後就清掉。
# 原本用 active_risk_event_id(=目前選取的鏡像)來強制 selectbox,導致
# 使用者在下拉選另一個事件時,rerun 又被拉回上一個,永遠切不過去。
target_id = st.session_state.pop("jump_to_risk_event_id", None)
if target_id is not None and target_id in event_ids: # event_ids[0] 是佔位的 None
st.session_state["resp_active_event_sel"] = event_ids.index(target_id)
elif st.session_state["resp_active_event_sel"] >= len(event_options):
st.session_state["resp_active_event_sel"] = 0 # 事件被刪除後索引失效

selected_idx = st.selectbox(
"選擇要分析與執行的風險事件",
Expand Down
3 changes: 2 additions & 1 deletion frontend/components/supply_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ def render_risk_shortcuts(key: str, heatmap_rows=None, *, actor: str):

if btn_state == "view":
if st.button("📊 查看分析", key=f"{key}_quick_anal_{region_key}_{i}", use_container_width=True, type="secondary"):
st.session_state["active_risk_event_id"] = found_ev["id"]
# 一次性的跳轉指令;active_risk_event_id 只反映目前選取,不用來強制 selectbox
st.session_state["jump_to_risk_event_id"] = found_ev["id"]
st.rerun()
elif btn_state == "update":
if st.button("🔄 更新應變建議", key=f"{key}_upd_{region_key}", use_container_width=True, type="primary"):
Expand Down
38 changes: 38 additions & 0 deletions tests/test_step3_event_switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
tests/test_step3_event_switch.py
步驟 3 事件下拉:有多個正式事件時,使用者必須能從 A 切到 B。

原本卡片「查看分析」和 selectbox 都寫 active_risk_event_id,而 rerun 時又用它
強制覆寫 selectbox,於是選了 B 也會被拉回 A。跳轉改成一次性的 jump_to_risk_event_id。
"""

from __future__ import annotations

import ast
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]


def _assigned_keys(tree):
keys = set()
for node in ast.walk(tree):
if isinstance(node, ast.Assign):
for target in node.targets:
if (isinstance(target, ast.Subscript)
and isinstance(target.value, ast.Attribute)
and target.value.attr == "session_state"
and isinstance(target.slice, ast.Constant)):
keys.add(target.slice.value)
return keys


def test_card_jump_uses_one_shot_key_and_step3_consumes_it():
supply_map = ast.parse((ROOT / "frontend/components/supply_map.py").read_text(encoding="utf-8"))
dashboard_src = (ROOT / "frontend/components/risk_dashboard.py").read_text(encoding="utf-8")

assert "jump_to_risk_event_id" in _assigned_keys(supply_map)
assert "active_risk_event_id" not in _assigned_keys(supply_map)
# 步驟 3 取出即清除,且不再拿 active_risk_event_id 去覆寫 selectbox
assert 'st.session_state.pop("jump_to_risk_event_id"' in dashboard_src
assert 'target_id = st.session_state["active_risk_event_id"]' not in dashboard_src
Loading