un2266 commited on
Commit
6ac48e6
·
1 Parent(s): 761ab7f

E3:清除 scenario_btn_col 死碼 wiring

Browse files

Phase 8 留下的空 Column(純為既有可見性 wiring 保留,selection buttons
早已搬到 homepage_col/scenario_select_row),整段移除:
- 宣告本身與對應 CSS(.scenario-buttons 相關規則,含收合狀態覆寫)
- on_scenario_pick 四個 yield/outputs 清單移除該 output slot
- on_reset_confirm 移除該 output slot,回傳 tuple 9→8 個元素

Playwright 驗證:情境選擇(1/3)、格式要求文案、重新選擇研究情境、
回首頁重置後再選情境,皆正常無 console/server error。

Files changed (1) hide show
  1. app_agent.py +23 -56
app_agent.py CHANGED
@@ -2658,12 +2658,6 @@ div[role="log"][aria-label="chatbot conversation"],
2658
  padding-top: .6rem !important;
2659
  border-top: 1px solid var(--c-border) !important;
2660
  }
2661
- /* 5-D:scenario_btn_col 是 Phase 8 留下的空 Column(只為既有可見性 wiring
2662
- 保留,E3 待清)。它夾在頂端列與「開始新分析」之間,即使沒內容,flex gap
2663
- 仍會在它前後各插一份間距,把兩者推遠(這正是千卉回報的「間距太遠」)。
2664
- 直接 display:none 讓它退出 flex 排版、間距歸零;wiring 對它設 visible 仍
2665
- 可跑、只是視覺無效果(本來就空的)。 */
2666
- .scenario-buttons { display: none !important; }
2667
  /* 真因排查記錄:Gradio 的 .column 預設會帶 flex-wrap:wrap。平常沒設高度時
2668
  不會有事,但這裡額外設了固定 height 讓內容用捲動取代撐高,一旦內容總高
2669
  度超過這個 height,flex-wrap:wrap 會把「排不下」的子元件換到*右邊新開一
@@ -2801,20 +2795,6 @@ div[role="log"][aria-label="chatbot conversation"],
2801
  flex-shrink: 0 !important;
2802
  }
2803
 
2804
- /* ── 5c. SCENARIO BUTTONS(取代原本打字輸入研究情境的輸入列)────────── */
2805
- .scenario-buttons {
2806
- margin-top: .6rem !important;
2807
- gap: .5rem !important;
2808
- }
2809
- .scenario-buttons button {
2810
- width: 100% !important;
2811
- justify-content: flex-start !important;
2812
- text-align: left !important;
2813
- padding: .85rem 1.1rem !important;
2814
- border-radius: 10px !important;
2815
- font-weight: 600 !important;
2816
- font-size: var(--font-size-base) !important;
2817
- }
2818
  /* ── 5d. HOMEPAGE(Phase 8:首頁 4 張情境卡片)──────────────────── */
2819
  /* 隱藏版情境按鈕:純作 JS 橋接目標(見 _APP_HEAD_SCRIPT),
2820
  點卡片=模擬點這裡的按鈕,Python 端 .click() 綁定完全不動。
@@ -3085,7 +3065,6 @@ img.button-icon { opacity: .82; }
3085
  /* .reset-confirm 已於 2026-07-24 搬出 nav-col 改成全螢幕 modal,
3086
  不再需要在收合狀態下隱藏;.result-nav-accordion 同日隨「統計比較
3087
  分析」手風琴一起移除。 */
3088
- .nav-col.collapsed .scenario-buttons,
3089
  .nav-col.collapsed .result-nav-divider { display: none !important; }
3090
  /* 選擇器裡的 #result_nav_col 是為了贏過下方 nav-underline 樣式的
3091
  `#result_nav_col .result-nav-btn`(1 個 id + 1 個 class = 1,1,0)。
@@ -4900,20 +4879,10 @@ def create_app():
4900
  elem_id="nav_top_html",
4901
  )
4902
 
4903
- # 中段可捲動區:研究情境(已隱藏的空殼)、回首頁連結、結果導覽
4904
- # 全部包進來,只有這個 Column 自己 overflow-y:auto(見
4905
- # .nav-items-scroll CSS),不影響上下兩段固定區塊。
4906
  with gr.Column(elem_classes=["nav-items-scroll"]) as nav_items_scroll:
4907
- # 研究情境是封閉式的固定四選一,改用可點擊按鈕取代打字輸入
4908
- # 數字再解析,選定後即隱藏,對話視窗回歸純輸出角色
4909
- # Phase 8:情境選擇按鈕已搬到 homepage_col(見上方,理由是
4910
- # Gradio 對建構時 visible=False 的容器不掛載進 DOM,見該處
4911
- # 註解)。這個 Column 目前是空的,只留來讓 on_scenario_pick/
4912
- # on_reset_confirm 既有的可見性輸出繼續運作,不動更多 wiring;
4913
- # Phase 8-F 全站清理時一併拿掉。
4914
- with gr.Column(elem_classes=["scenario-buttons"]) as scenario_btn_col:
4915
- pass
4916
-
4917
  # 「回首頁」連結與其確認彈窗:換情境/回首頁都走這一套共用
4918
  # 機制。情境是封閉式按鈕選擇,不透過對話框打字,所以「換
4919
  # 情境」也統一走這顆按鈕,不恢復文字解析路徑。
@@ -5845,7 +5814,7 @@ def create_app():
5845
  # 值,不管它是怎麼還原回來的。
5846
  def on_scenario_pick(sc_num, chat_history, log_history, state):
5847
  if state is None:
5848
- yield (chat_history, log_history, state, gr.update(), gr.update(), gr.update(), gr.update(),
5849
  gr.update(), gr.update(), gr.update(), gr.update(),
5850
  gr.update(), gr.update(), gr.update(), gr.update(),
5851
  gr.update())
@@ -5862,7 +5831,7 @@ def create_app():
5862
  # 東西可看,不用透過 _populate_tabs 的檔案存在判斷來決定可見性。
5863
  # 這幾個 visibility 只需要在第一個 yield 就切換一次,後續 yield
5864
  # 沿用 gr.update() 不動即可,不用每次都重複賦值。
5865
- yield (chat_history, log_history, state, gr.update(), gr.update(), gr.update(), gr.update(),
5866
  gr.update(visible=False), gr.update(visible=True), gr.update(visible=True),
5867
  gr.update(visible=True),
5868
  gr.update(), gr.update(), gr.update(), gr.update(),
@@ -5881,7 +5850,7 @@ def create_app():
5881
  # 自己對它們下的 visible=False 更新互相打架、我們的更新輸了。
5882
  # 等 workspace_row 的翻轉已經在前一個 yield 處理完、沉澱下來,
5883
  # 這一個 yield 才不會再觸發同一種還原,我們的 False 才是最後贏家。
5884
- yield (chat_history, log_history, state, gr.update(), _todo_update(state), gr.update(), gr.update(),
5885
  gr.update(), gr.update(), gr.update(), gr.update(),
5886
  gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
5887
  gr.update(visible=False),
@@ -5897,19 +5866,17 @@ def create_app():
5897
  state["current_step"] = 2
5898
  state["state"] = "UPLOAD_WAIT"
5899
  log_history = _log_append(log_history, "⏳ 等待上傳文本……")
5900
- # 情境已選定,研究選擇區塊收起、換上傳卡片出現(3-A 延伸:原本
5901
- # 這裡只切 scenario_btn_col/upload_hint_md,現在 scenario_select_row
5902
- # 也在同一個 yield 一起隱藏——這個 yield 離 workspace_row 自身的
5903
- # True/False 翻轉已經隔了兩個 yield,不受本函式上方記錄的 Gradio
5904
- # 6 still-mounted-snapback 地雷影響,可以放心跟其他更新同批)。
5905
- # 對話視窗自此回歸純輸出角色。格式要求直接寫進上傳卡片本身
5906
- # (upload_hint_md),使用者不用往上捲回對話視窗找 AI 剛剛說過的
5907
- # 規則——卡片本身就要自己講清楚。
5908
  hint = (
5909
  f"**格式要求**\n\n{sc_info['upload_prompt']}"
5910
  )
5911
  yield (chat_history, log_history, state, gr.update(visible=True),
5912
- _todo_update(state), gr.update(visible=False), gr.update(value=hint),
5913
  gr.update(), gr.update(), gr.update(), gr.update(),
5914
  gr.update(), gr.update(), gr.update(), gr.update(),
5915
  gr.update(visible=False))
@@ -5918,7 +5885,7 @@ def create_app():
5918
  _sc_btn.click(
5919
  fn=functools.partial(on_scenario_pick, _sc_num),
5920
  inputs=[chatbot, exec_log, session_state],
5921
- outputs=[chatbot, exec_log, session_state, upload_row, app_header_html, scenario_btn_col,
5922
  upload_hint_md, homepage_col, workspace_row, result_nav_col, canvas_exec_col,
5923
  metadata_row, canvas_idx_col, canvas_stat_col, canvas_report_col,
5924
  scenario_select_row],
@@ -5928,10 +5895,10 @@ def create_app():
5928
  outputs=_TAB_OUTPUTS,
5929
  )
5930
 
5931
- # ── 「開始新分析」:Bug1 修復——scenario_btn_col 一旦隱藏,先前完全沒有
5932
- # 任何路徑能設回 visible=True,使用者選錯情境後無法變更。這裡補上
5933
- # 共用的重置機制:換情境=重新開始,統一走這顆按鈕(不恢復對話框
5934
- # 打字選情境的舊路徑)──────────────────────────────────────────
5935
  # Bug 4-C 修復(2026-07-30):Gradio 6 的 gr.Column/Row(visible=False)
5936
  # 會把��元件整段從 DOM 卸載,不只是 CSS 隱藏。原本 on_reset_confirm
5937
  # 在同一個 return 裡,一邊把 workspace_row 設 visible=False,一邊又要
@@ -5974,7 +5941,6 @@ def create_app():
5974
  new_log, # exec_log
5975
  state, # session_state
5976
  gr.update(value=_build_header_html()), # app_header_html
5977
- gr.update(visible=True), # scenario_btn_col(Bug1 關鍵一行)
5978
  gr.update(visible=False), # upload_row(Phase 8:正式上傳入口改這張卡片)
5979
  gr.update(visible=False), # reset_confirm_row(關掉確認彈窗自己)
5980
  gr.update(visible=True), # homepage_col(Phase 8:重新開始=回到首頁選情境)
@@ -5991,11 +5957,12 @@ def create_app():
5991
  ).then(
5992
  fn=on_reset_confirm,
5993
  # 2026-07-30(2-C 第 5 項):chat_upload 這輪常駐隱藏、不再接任何
5994
- # wiring(見 chat_upload_col 定義處註解),這裡把它從 outputs 移除,
5995
- # 不留無意義的清空動作。回傳 tuple 的元素個數/順序已同步調整為
5996
- # 9 個,跟這份 outputs 清單一一對應。
 
5997
  outputs=[chatbot, exec_log, session_state, app_header_html,
5998
- scenario_btn_col, upload_row,
5999
  reset_confirm_row, homepage_col, workspace_row],
6000
  )
6001
 
 
2658
  padding-top: .6rem !important;
2659
  border-top: 1px solid var(--c-border) !important;
2660
  }
 
 
 
 
 
 
2661
  /* 真因排查記錄:Gradio 的 .column 預設會帶 flex-wrap:wrap。平常沒設高度時
2662
  不會有事,但這裡額外設了固定 height 讓內容用捲動取代撐高,一旦內容總高
2663
  度超過這個 height,flex-wrap:wrap 會把「排不下」的子元件換到*右邊新開一
 
2795
  flex-shrink: 0 !important;
2796
  }
2797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2798
  /* ── 5d. HOMEPAGE(Phase 8:首頁 4 張情境卡片)──────────────────── */
2799
  /* 隱藏版情境按鈕:純作 JS 橋接目標(見 _APP_HEAD_SCRIPT),
2800
  點卡片=模擬點這裡的按鈕,Python 端 .click() 綁定完全不動。
 
3065
  /* .reset-confirm 已於 2026-07-24 搬出 nav-col 改成全螢幕 modal,
3066
  不再需要在收合狀態下隱藏;.result-nav-accordion 同日隨「統計比較
3067
  分析」手風琴一起移除。 */
 
3068
  .nav-col.collapsed .result-nav-divider { display: none !important; }
3069
  /* 選擇器裡的 #result_nav_col 是為了贏過下方 nav-underline 樣式的
3070
  `#result_nav_col .result-nav-btn`(1 個 id + 1 個 class = 1,1,0)。
 
4879
  elem_id="nav_top_html",
4880
  )
4881
 
4882
+ # 中段可捲動區:回首頁連結、結果導覽全部包進來,只有這個
4883
+ # Column 自己 overflow-y:auto(見 .nav-items-scroll CSS),
4884
+ # 不影響上下兩段固定區塊。
4885
  with gr.Column(elem_classes=["nav-items-scroll"]) as nav_items_scroll:
 
 
 
 
 
 
 
 
 
 
4886
  # 「回首頁」連結與其確認彈窗:換情境/回首頁都走這一套共用
4887
  # 機制。情境是封閉式按鈕選擇,不透過對話框打字,所以「換
4888
  # 情境」也統一走這顆按鈕,不恢復文字解析路徑。
 
5814
  # 值,不管它是怎麼還原回來的。
5815
  def on_scenario_pick(sc_num, chat_history, log_history, state):
5816
  if state is None:
5817
+ yield (chat_history, log_history, state, gr.update(), gr.update(), gr.update(),
5818
  gr.update(), gr.update(), gr.update(), gr.update(),
5819
  gr.update(), gr.update(), gr.update(), gr.update(),
5820
  gr.update())
 
5831
  # 東西可看,不用透過 _populate_tabs 的檔案存在判斷來決定可見性。
5832
  # 這幾個 visibility 只需要在第一個 yield 就切換一次,後續 yield
5833
  # 沿用 gr.update() 不動即可,不用每次都重複賦值。
5834
+ yield (chat_history, log_history, state, gr.update(), gr.update(), gr.update(),
5835
  gr.update(visible=False), gr.update(visible=True), gr.update(visible=True),
5836
  gr.update(visible=True),
5837
  gr.update(), gr.update(), gr.update(), gr.update(),
 
5850
  # 自己對它們下的 visible=False 更新互相打架、我們的更新輸了。
5851
  # 等 workspace_row 的翻轉已經在前一個 yield 處理完、沉澱下來,
5852
  # 這一個 yield 才不會再觸發同一種還原,我們的 False 才是最後贏家。
5853
+ yield (chat_history, log_history, state, gr.update(), _todo_update(state), gr.update(),
5854
  gr.update(), gr.update(), gr.update(), gr.update(),
5855
  gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
5856
  gr.update(visible=False),
 
5866
  state["current_step"] = 2
5867
  state["state"] = "UPLOAD_WAIT"
5868
  log_history = _log_append(log_history, "⏳ 等待上傳文本……")
5869
+ # 情境已選定,研究選擇區塊收起、換上傳卡片出現。這個 yield 離
5870
+ # workspace_row 自身的 True/False 翻轉已經隔了兩個 yield,不受
5871
+ # 本函式上方記錄的 Gradio 6 still-mounted-snapback 地雷影響,
5872
+ # 可以放心跟其他更新同批。對話視窗自此回歸純輸出角色。格式要求
5873
+ # 直接寫進上傳卡片本身(upload_hint_md),使用者不用往上捲回
5874
+ # 對話視窗找 AI 剛剛說過的規則——卡片本身就要自己講清楚。
 
 
5875
  hint = (
5876
  f"**格式要求**\n\n{sc_info['upload_prompt']}"
5877
  )
5878
  yield (chat_history, log_history, state, gr.update(visible=True),
5879
+ _todo_update(state), gr.update(value=hint),
5880
  gr.update(), gr.update(), gr.update(), gr.update(),
5881
  gr.update(), gr.update(), gr.update(), gr.update(),
5882
  gr.update(visible=False))
 
5885
  _sc_btn.click(
5886
  fn=functools.partial(on_scenario_pick, _sc_num),
5887
  inputs=[chatbot, exec_log, session_state],
5888
+ outputs=[chatbot, exec_log, session_state, upload_row, app_header_html,
5889
  upload_hint_md, homepage_col, workspace_row, result_nav_col, canvas_exec_col,
5890
  metadata_row, canvas_idx_col, canvas_stat_col, canvas_report_col,
5891
  scenario_select_row],
 
5895
  outputs=_TAB_OUTPUTS,
5896
  )
5897
 
5898
+ # ── 「開始新分析」:Bug1 修復——選定情境後先前完全沒有任何路徑能
5899
+ # 回頭變更,使用者選錯情境後卡住。這裡補上共用的重置機制:換情境
5900
+ # =重新開始,統一走這顆按鈕回到首頁重新選(不恢復對話框打字選
5901
+ # 情境的舊路徑)────────────────────────────────────────────────
5902
  # Bug 4-C 修復(2026-07-30):Gradio 6 的 gr.Column/Row(visible=False)
5903
  # 會把��元件整段從 DOM 卸載,不只是 CSS 隱藏。原本 on_reset_confirm
5904
  # 在同一個 return 裡,一邊把 workspace_row 設 visible=False,一邊又要
 
5941
  new_log, # exec_log
5942
  state, # session_state
5943
  gr.update(value=_build_header_html()), # app_header_html
 
5944
  gr.update(visible=False), # upload_row(Phase 8:正式上傳入口改這張卡片)
5945
  gr.update(visible=False), # reset_confirm_row(關掉確認彈窗自己)
5946
  gr.update(visible=True), # homepage_col(Phase 8:重新開始=回到首頁選情境)
 
5957
  ).then(
5958
  fn=on_reset_confirm,
5959
  # 2026-07-30(2-C 第 5 項):chat_upload 這輪常駐隱藏、不再接任何
5960
+ # wiring(見 chat_upload_col 定義處註解),這裡把它從 outputs 移除。
5961
+ # E3(2026-08-05):scenario_btn_col 空 Column 已整段拿掉,一併從
5962
+ # outputs 移除。回傳 tuple 的元素個數/順序已同步調整為 8 個,
5963
+ # 跟這份 outputs 清單一一對應。
5964
  outputs=[chatbot, exec_log, session_state, app_header_html,
5965
+ upload_row,
5966
  reset_confirm_row, homepage_col, workspace_row],
5967
  )
5968