Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -196,12 +196,15 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
196 |
logging.error(f"Config not found for plot_id {plot_id_clicked}")
|
197 |
# Ensure this error return matches the expected number of outputs
|
198 |
num_plots = len(plot_configs)
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
error_list
|
203 |
-
|
204 |
-
error_list
|
|
|
|
|
|
|
205 |
return error_list
|
206 |
|
207 |
clicked_plot_label = clicked_plot_config["label"]
|
@@ -212,7 +215,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
212 |
action_col_visible_update = gr.update(visible=False)
|
213 |
insights_chatbot_visible_update, insights_chat_input_visible_update, insights_suggestions_row_visible_update = gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
|
214 |
formula_display_visible_update = gr.update(visible=False)
|
215 |
-
formula_close_hint_visible_update = gr.update(visible=False)
|
216 |
chatbot_content_update, s1_upd, s2_upd, s3_upd, formula_content_update = gr.update(), gr.update(), gr.update(), gr.update(), gr.update()
|
217 |
|
218 |
new_active_action_state_to_set, new_current_chat_plot_id = None, current_chat_plot_id
|
@@ -223,10 +226,9 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
223 |
|
224 |
if is_toggling_off:
|
225 |
new_active_action_state_to_set = None
|
226 |
-
action_col_visible_update = gr.update(visible=False)
|
227 |
-
# formula_close_hint_visible_update is already set to hidden by default
|
228 |
logging.info(f"Toggling OFF panel {action_type} for {plot_id_clicked}.")
|
229 |
-
if current_explored_plot_id:
|
230 |
explored_cfg = next((p for p in plot_configs if p["id"] == current_explored_plot_id), None)
|
231 |
explored_sec = explored_cfg["section"] if explored_cfg else None
|
232 |
for i, sec_name in enumerate(unique_ordered_sections):
|
@@ -235,28 +237,28 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
235 |
is_exp = (cfg["id"] == current_explored_plot_id)
|
236 |
panel_vis_updates.append(gr.update(visible=is_exp))
|
237 |
explore_btn_updates.append(gr.update(value=ACTIVE_ICON if is_exp else EXPLORE_ICON))
|
238 |
-
else:
|
239 |
for i in range(num_unique_sections): section_title_vis_updates[i] = gr.update(visible=True)
|
240 |
for _ in plot_configs:
|
241 |
panel_vis_updates.append(gr.update(visible=True))
|
242 |
explore_btn_updates.append(gr.update(value=EXPLORE_ICON))
|
243 |
-
for _ in plot_configs:
|
244 |
action_btn_updates.extend([gr.update(value=BOMB_ICON), gr.update(value=FORMULA_ICON)])
|
245 |
if action_type == "insights": new_current_chat_plot_id = None
|
246 |
|
247 |
-
else:
|
248 |
new_active_action_state_to_set = hypothetical_new_active_state
|
249 |
-
action_col_visible_update = gr.update(visible=True)
|
250 |
-
new_explored_plot_id_to_set = None
|
251 |
logging.info(f"Toggling ON panel {action_type} for {plot_id_clicked}. Cancelling explore view.")
|
252 |
|
253 |
-
for i, sec_name in enumerate(unique_ordered_sections):
|
254 |
section_title_vis_updates[i] = gr.update(visible=(sec_name == clicked_plot_section))
|
255 |
-
for cfg in plot_configs:
|
256 |
panel_vis_updates.append(gr.update(visible=(cfg["id"] == plot_id_clicked)))
|
257 |
-
explore_btn_updates.append(gr.update(value=EXPLORE_ICON))
|
258 |
|
259 |
-
for cfg_btn in plot_configs:
|
260 |
is_act_ins = new_active_action_state_to_set == {"plot_id": cfg_btn["id"], "type": "insights"}
|
261 |
is_act_for = new_active_action_state_to_set == {"plot_id": cfg_btn["id"], "type": "formula"}
|
262 |
action_btn_updates.extend([gr.update(value=ACTIVE_ICON if is_act_ins else BOMB_ICON),
|
@@ -277,7 +279,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
277 |
s1_upd,s2_upd,s3_upd = gr.update(value=sugg[0] if sugg else "N/A"),gr.update(value=sugg[1] if len(sugg)>1 else "N/A"),gr.update(value=sugg[2] if len(sugg)>2 else "N/A")
|
278 |
elif action_type == "formula":
|
279 |
formula_display_visible_update = gr.update(visible=True)
|
280 |
-
formula_close_hint_visible_update = gr.update(visible=True)
|
281 |
f_key = PLOT_ID_TO_FORMULA_KEY_MAP.get(plot_id_clicked)
|
282 |
f_text = f"**Formula/Methodology for: {clicked_plot_label}** (ID: `{plot_id_clicked}`)\n\n"
|
283 |
if f_key and f_key in PLOT_FORMULAS:
|
@@ -291,14 +293,16 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
291 |
action_col_visible_update, insights_chatbot_visible_update, chatbot_content_update,
|
292 |
insights_chat_input_visible_update, insights_suggestions_row_visible_update,
|
293 |
s1_upd, s2_upd, s3_upd, formula_display_visible_update, formula_content_update,
|
294 |
-
formula_close_hint_visible_update,
|
295 |
new_active_action_state_to_set, new_current_chat_plot_id, updated_chat_histories,
|
296 |
new_explored_plot_id_to_set
|
297 |
]
|
298 |
final_updates.extend(panel_vis_updates)
|
299 |
-
final_updates.extend(action_btn_updates)
|
300 |
-
final_updates.extend(explore_btn_updates)
|
301 |
final_updates.extend(section_title_vis_updates)
|
|
|
|
|
302 |
return final_updates
|
303 |
|
304 |
async def handle_chat_message_submission(user_message: str, current_plot_id: str, chat_histories: dict, current_plot_data_for_chatbot: dict ):
|
@@ -323,16 +327,20 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
323 |
num_plots = len(plot_configs)
|
324 |
if not plot_ui_objects:
|
325 |
logging.error("plot_ui_objects not populated for handle_explore_click.")
|
326 |
-
#
|
327 |
-
|
328 |
-
|
329 |
-
|
|
|
|
|
|
|
|
|
330 |
|
331 |
new_explored_id_to_set, is_toggling_off_explore = None, (plot_id_clicked == current_explored_plot_id_from_state)
|
332 |
action_col_upd, new_active_panel_state_upd = gr.update(), current_active_panel_action_state
|
333 |
panel_vis, explore_btns, bomb_btns, formula_btns = [], [], [], []
|
334 |
section_title_vis = [gr.update()] * num_unique_sections
|
335 |
-
formula_hint_upd = gr.update(visible=False)
|
336 |
|
337 |
clicked_cfg = next((p for p in plot_configs if p["id"] == plot_id_clicked), None)
|
338 |
sec_of_clicked = clicked_cfg["section"] if clicked_cfg else None
|
@@ -343,48 +351,65 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
343 |
for i in range(num_unique_sections): section_title_vis[i] = gr.update(visible=True)
|
344 |
for _ in plot_configs:
|
345 |
panel_vis.append(gr.update(visible=True)); explore_btns.append(gr.update(value=EXPLORE_ICON))
|
346 |
-
bomb_btns.append(gr.update()); formula_btns.append(gr.update())
|
347 |
else:
|
348 |
new_explored_id_to_set = plot_id_clicked
|
349 |
logging.info(f"Exploring {plot_id_clicked}. Hiding other plots/sections.")
|
350 |
for i, sec_name in enumerate(unique_ordered_sections): section_title_vis[i] = gr.update(visible=(sec_name == sec_of_clicked))
|
351 |
-
for cfg in plot_configs:
|
352 |
is_target = (cfg["id"] == new_explored_id_to_set)
|
353 |
-
panel_vis.append(gr.update(visible=is_target))
|
354 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
logging.info("Closing active insight/formula panel due to explore click.")
|
356 |
action_col_upd = gr.update(visible=False); new_active_panel_state_upd = None
|
357 |
-
|
|
|
|
|
358 |
else:
|
359 |
-
|
|
|
|
|
360 |
|
|
|
|
|
361 |
return [new_explored_id_to_set, action_col_upd, new_active_panel_state_upd, formula_hint_upd] + \
|
362 |
panel_vis + explore_btns + bomb_btns + formula_btns + section_title_vis
|
363 |
|
364 |
# --- Define Output Lists for Event Handlers ---
|
|
|
365 |
_base_action_panel_ui_outputs = [
|
366 |
global_actions_column_ui, insights_chatbot_ui, insights_chatbot_ui,
|
367 |
insights_chat_input_ui, insights_suggestions_row_ui,
|
368 |
insights_suggestion_1_btn, insights_suggestion_2_btn, insights_suggestion_3_btn,
|
369 |
-
formula_display_markdown_ui, formula_display_markdown_ui,
|
370 |
-
formula_close_hint_md
|
371 |
]
|
|
|
372 |
_action_panel_state_outputs = [active_panel_action_state, current_chat_plot_id_st, chat_histories_st, explored_plot_id_state]
|
373 |
|
374 |
-
action_panel_outputs_list = _base_action_panel_ui_outputs + _action_panel_state_outputs
|
375 |
-
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("panel_component", gr.update()) for pc in plot_configs]) #
|
376 |
-
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("bomb_button", gr.update()) for pc in plot_configs]) #
|
377 |
-
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("formula_button", gr.update()) for pc in plot_configs]) #
|
378 |
-
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("explore_button", gr.update()) for pc in plot_configs]) #
|
379 |
-
action_panel_outputs_list.extend([section_titles_map.get(s_name, gr.update()) for s_name in unique_ordered_sections]) #
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
explore_outputs_list
|
385 |
-
explore_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("
|
386 |
-
explore_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("
|
387 |
-
explore_outputs_list.extend([
|
|
|
|
|
|
|
388 |
|
389 |
action_click_inputs = [active_panel_action_state, chat_histories_st, current_chat_plot_id_st, plot_data_for_chatbot_st, explored_plot_id_state]
|
390 |
explore_click_inputs = [explored_plot_id_state, active_panel_action_state]
|
@@ -416,46 +441,47 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
416 |
plot_gen_results = update_analytics_plots_figures(current_token_state, date_filter_val, custom_start_val, custom_end_val, plot_configs)
|
417 |
status_msg, gen_figs, new_summaries = plot_gen_results[0], plot_gen_results[1:-1], plot_gen_results[-1]
|
418 |
|
419 |
-
all_updates = [status_msg]
|
420 |
-
all_updates.extend(gen_figs if len(gen_figs) == len(plot_configs) else [create_placeholder_plot("Error", f"Fig missing {i}") for i in range(len(plot_configs))])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
|
422 |
-
all_updates.extend([ # Reset action panel UI (11 elements including new hint)
|
423 |
-
gr.update(visible=False), gr.update(value=[], visible=False), gr.update(value="", visible=False),
|
424 |
-
gr.update(visible=False), gr.update(value="S1"), gr.update(value="S2"), gr.update(value="S3"),
|
425 |
-
gr.update(value="Formula details here.", visible=False), gr.update(visible=False), # Formula MD and Hint MD
|
426 |
-
None, None, {}, new_summaries # Reset states (4 elements)
|
427 |
-
]) # Total 11 + 4 = 15 here
|
428 |
-
for _ in plot_configs: # Reset button icons & panel visibility (4 per plot)
|
429 |
-
all_updates.extend([gr.update(value=BOMB_ICON), gr.update(value=FORMULA_ICON), gr.update(value=EXPLORE_ICON), gr.update(visible=True)])
|
430 |
all_updates.append(None) # Reset explored_plot_id_state (1 element)
|
431 |
-
all_updates.extend([gr.update(visible=True)] * num_unique_sections) # Make all section titles visible (M elements)
|
|
|
432 |
logging.info(f"Prepared {len(all_updates)} updates for analytics refresh.")
|
433 |
return all_updates
|
434 |
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
active_panel_action_state, current_chat_plot_id_st, chat_histories_st, plot_data_for_chatbot_st # States (4) -> total 11+4 = 15 for this block
|
442 |
-
]) # This was 12, now 13 with hint. State resets are separate. Let's be precise.
|
443 |
-
# Action Panel UI (9) + Formula MD (1) + Hint MD (1) = 11
|
444 |
-
# States (4) = active_panel_action_state, current_chat_plot_id_st, chat_histories_st, plot_data_for_chatbot_st
|
445 |
-
# So, 11 UI + 4 states = 15 elements.
|
446 |
|
447 |
-
#
|
448 |
_ui_resets_for_filter = [
|
449 |
global_actions_column_ui, insights_chatbot_ui, insights_chat_input_ui,
|
450 |
insights_suggestions_row_ui, insights_suggestion_1_btn, insights_suggestion_2_btn, insights_suggestion_3_btn,
|
451 |
-
formula_display_markdown_ui, formula_close_hint_md
|
452 |
]
|
453 |
-
_state_resets_for_filter = [active_panel_action_state, current_chat_plot_id_st, chat_histories_st, plot_data_for_chatbot_st] # 4 elements
|
454 |
-
|
455 |
apply_filter_and_sync_outputs_list.extend(_ui_resets_for_filter)
|
|
|
|
|
|
|
456 |
apply_filter_and_sync_outputs_list.extend(_state_resets_for_filter)
|
457 |
|
458 |
-
|
|
|
459 |
pid = pc["id"]
|
460 |
apply_filter_and_sync_outputs_list.extend([
|
461 |
plot_ui_objects.get(pid, {}).get("bomb_button", gr.update()),
|
@@ -463,8 +489,14 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
463 |
plot_ui_objects.get(pid, {}).get("explore_button", gr.update()),
|
464 |
plot_ui_objects.get(pid, {}).get("panel_component", gr.update())
|
465 |
])
|
466 |
-
|
467 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
|
469 |
apply_filter_btn.click(
|
470 |
fn=refresh_all_analytics_ui_elements,
|
|
|
196 |
logging.error(f"Config not found for plot_id {plot_id_clicked}")
|
197 |
# Ensure this error return matches the expected number of outputs
|
198 |
num_plots = len(plot_configs)
|
199 |
+
# Count for action_panel_outputs_list: 11 base UI + 4 states + N panels + 3N buttons + M sections = 15 + 4N + M
|
200 |
+
# 15 + 4*19 + 6 = 15 + 76 + 6 = 97
|
201 |
+
error_list_len = 11 + 4 + num_plots + (3 * num_plots) + num_unique_sections # Matches action_panel_outputs_list structure
|
202 |
+
error_list = [gr.update()] * error_list_len
|
203 |
+
# Manually set key states to avoid further issues if possible
|
204 |
+
error_list[11] = current_active_action_from_state # active_panel_action_state
|
205 |
+
error_list[12] = current_chat_plot_id # current_chat_plot_id_st
|
206 |
+
error_list[13] = current_chat_histories # chat_histories_st
|
207 |
+
error_list[14] = current_explored_plot_id # explored_plot_id_state
|
208 |
return error_list
|
209 |
|
210 |
clicked_plot_label = clicked_plot_config["label"]
|
|
|
215 |
action_col_visible_update = gr.update(visible=False)
|
216 |
insights_chatbot_visible_update, insights_chat_input_visible_update, insights_suggestions_row_visible_update = gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)
|
217 |
formula_display_visible_update = gr.update(visible=False)
|
218 |
+
formula_close_hint_visible_update = gr.update(visible=False)
|
219 |
chatbot_content_update, s1_upd, s2_upd, s3_upd, formula_content_update = gr.update(), gr.update(), gr.update(), gr.update(), gr.update()
|
220 |
|
221 |
new_active_action_state_to_set, new_current_chat_plot_id = None, current_chat_plot_id
|
|
|
226 |
|
227 |
if is_toggling_off:
|
228 |
new_active_action_state_to_set = None
|
229 |
+
action_col_visible_update = gr.update(visible=False)
|
|
|
230 |
logging.info(f"Toggling OFF panel {action_type} for {plot_id_clicked}.")
|
231 |
+
if current_explored_plot_id:
|
232 |
explored_cfg = next((p for p in plot_configs if p["id"] == current_explored_plot_id), None)
|
233 |
explored_sec = explored_cfg["section"] if explored_cfg else None
|
234 |
for i, sec_name in enumerate(unique_ordered_sections):
|
|
|
237 |
is_exp = (cfg["id"] == current_explored_plot_id)
|
238 |
panel_vis_updates.append(gr.update(visible=is_exp))
|
239 |
explore_btn_updates.append(gr.update(value=ACTIVE_ICON if is_exp else EXPLORE_ICON))
|
240 |
+
else:
|
241 |
for i in range(num_unique_sections): section_title_vis_updates[i] = gr.update(visible=True)
|
242 |
for _ in plot_configs:
|
243 |
panel_vis_updates.append(gr.update(visible=True))
|
244 |
explore_btn_updates.append(gr.update(value=EXPLORE_ICON))
|
245 |
+
for _ in plot_configs:
|
246 |
action_btn_updates.extend([gr.update(value=BOMB_ICON), gr.update(value=FORMULA_ICON)])
|
247 |
if action_type == "insights": new_current_chat_plot_id = None
|
248 |
|
249 |
+
else:
|
250 |
new_active_action_state_to_set = hypothetical_new_active_state
|
251 |
+
action_col_visible_update = gr.update(visible=True)
|
252 |
+
new_explored_plot_id_to_set = None
|
253 |
logging.info(f"Toggling ON panel {action_type} for {plot_id_clicked}. Cancelling explore view.")
|
254 |
|
255 |
+
for i, sec_name in enumerate(unique_ordered_sections):
|
256 |
section_title_vis_updates[i] = gr.update(visible=(sec_name == clicked_plot_section))
|
257 |
+
for cfg in plot_configs:
|
258 |
panel_vis_updates.append(gr.update(visible=(cfg["id"] == plot_id_clicked)))
|
259 |
+
explore_btn_updates.append(gr.update(value=EXPLORE_ICON))
|
260 |
|
261 |
+
for cfg_btn in plot_configs:
|
262 |
is_act_ins = new_active_action_state_to_set == {"plot_id": cfg_btn["id"], "type": "insights"}
|
263 |
is_act_for = new_active_action_state_to_set == {"plot_id": cfg_btn["id"], "type": "formula"}
|
264 |
action_btn_updates.extend([gr.update(value=ACTIVE_ICON if is_act_ins else BOMB_ICON),
|
|
|
279 |
s1_upd,s2_upd,s3_upd = gr.update(value=sugg[0] if sugg else "N/A"),gr.update(value=sugg[1] if len(sugg)>1 else "N/A"),gr.update(value=sugg[2] if len(sugg)>2 else "N/A")
|
280 |
elif action_type == "formula":
|
281 |
formula_display_visible_update = gr.update(visible=True)
|
282 |
+
formula_close_hint_visible_update = gr.update(visible=True)
|
283 |
f_key = PLOT_ID_TO_FORMULA_KEY_MAP.get(plot_id_clicked)
|
284 |
f_text = f"**Formula/Methodology for: {clicked_plot_label}** (ID: `{plot_id_clicked}`)\n\n"
|
285 |
if f_key and f_key in PLOT_FORMULAS:
|
|
|
293 |
action_col_visible_update, insights_chatbot_visible_update, chatbot_content_update,
|
294 |
insights_chat_input_visible_update, insights_suggestions_row_visible_update,
|
295 |
s1_upd, s2_upd, s3_upd, formula_display_visible_update, formula_content_update,
|
296 |
+
formula_close_hint_visible_update,
|
297 |
new_active_action_state_to_set, new_current_chat_plot_id, updated_chat_histories,
|
298 |
new_explored_plot_id_to_set
|
299 |
]
|
300 |
final_updates.extend(panel_vis_updates)
|
301 |
+
final_updates.extend(action_btn_updates) # Should be 2*N items
|
302 |
+
final_updates.extend(explore_btn_updates) # Should be N items
|
303 |
final_updates.extend(section_title_vis_updates)
|
304 |
+
# Total: 11 (base UI) + 4 (states) + N (panels) + 2N (action_btns) + N (explore_btns) + M (sections)
|
305 |
+
# = 15 + 4N + M. For N=19, M=6: 15 + 76 + 6 = 97. This matches action_panel_outputs_list.
|
306 |
return final_updates
|
307 |
|
308 |
async def handle_chat_message_submission(user_message: str, current_plot_id: str, chat_histories: dict, current_plot_data_for_chatbot: dict ):
|
|
|
327 |
num_plots = len(plot_configs)
|
328 |
if not plot_ui_objects:
|
329 |
logging.error("plot_ui_objects not populated for handle_explore_click.")
|
330 |
+
# explore_outputs_list: 4 base states/UI + N panels + N explore_btns + 2N action_btns + M sections
|
331 |
+
# = 4 + 4N + M. For N=19, M=6: 4 + 76 + 6 = 86
|
332 |
+
error_list_len = 4 + num_plots + num_plots + (2 * num_plots) + num_unique_sections
|
333 |
+
error_list = [gr.update()] * error_list_len
|
334 |
+
error_list[0] = current_explored_plot_id_from_state
|
335 |
+
error_list[2] = current_active_panel_action_state
|
336 |
+
return error_list
|
337 |
+
|
338 |
|
339 |
new_explored_id_to_set, is_toggling_off_explore = None, (plot_id_clicked == current_explored_plot_id_from_state)
|
340 |
action_col_upd, new_active_panel_state_upd = gr.update(), current_active_panel_action_state
|
341 |
panel_vis, explore_btns, bomb_btns, formula_btns = [], [], [], []
|
342 |
section_title_vis = [gr.update()] * num_unique_sections
|
343 |
+
formula_hint_upd = gr.update(visible=False)
|
344 |
|
345 |
clicked_cfg = next((p for p in plot_configs if p["id"] == plot_id_clicked), None)
|
346 |
sec_of_clicked = clicked_cfg["section"] if clicked_cfg else None
|
|
|
351 |
for i in range(num_unique_sections): section_title_vis[i] = gr.update(visible=True)
|
352 |
for _ in plot_configs:
|
353 |
panel_vis.append(gr.update(visible=True)); explore_btns.append(gr.update(value=EXPLORE_ICON))
|
354 |
+
bomb_btns.append(gr.update()); formula_btns.append(gr.update())
|
355 |
else:
|
356 |
new_explored_id_to_set = plot_id_clicked
|
357 |
logging.info(f"Exploring {plot_id_clicked}. Hiding other plots/sections.")
|
358 |
for i, sec_name in enumerate(unique_ordered_sections): section_title_vis[i] = gr.update(visible=(sec_name == sec_of_clicked))
|
359 |
+
for cfg_idx, cfg in enumerate(plot_configs): # Iterate with index for bomb_btns/formula_btns
|
360 |
is_target = (cfg["id"] == new_explored_id_to_set)
|
361 |
+
panel_vis.append(gr.update(visible=is_target))
|
362 |
+
explore_btns.append(gr.update(value=ACTIVE_ICON if is_target else EXPLORE_ICON))
|
363 |
+
# Initialize bomb_btns and formula_btns correctly for all plots
|
364 |
+
if current_active_panel_action_state and current_active_panel_action_state.get("plot_id") == cfg["id"]:
|
365 |
+
# This should not happen if we are closing active panel below
|
366 |
+
pass # Will be overridden
|
367 |
+
|
368 |
+
if current_active_panel_action_state:
|
369 |
logging.info("Closing active insight/formula panel due to explore click.")
|
370 |
action_col_upd = gr.update(visible=False); new_active_panel_state_upd = None
|
371 |
+
# Reset all bomb and formula buttons
|
372 |
+
bomb_btns = [gr.update(value=BOMB_ICON) for _ in plot_configs]
|
373 |
+
formula_btns = [gr.update(value=FORMULA_ICON) for _ in plot_configs]
|
374 |
else:
|
375 |
+
# If no panel was active, keep current state of bomb/formula buttons (no update)
|
376 |
+
bomb_btns = [gr.update() for _ in plot_configs]
|
377 |
+
formula_btns = [gr.update() for _ in plot_configs]
|
378 |
|
379 |
+
# Order: states (4), panels (N), explore_btns (N), bomb_btns (N), formula_btns (N), section_titles (M)
|
380 |
+
# Total: 4 + N + N + N + N + M = 4 + 4N + M.
|
381 |
return [new_explored_id_to_set, action_col_upd, new_active_panel_state_upd, formula_hint_upd] + \
|
382 |
panel_vis + explore_btns + bomb_btns + formula_btns + section_title_vis
|
383 |
|
384 |
# --- Define Output Lists for Event Handlers ---
|
385 |
+
# Base UI for action panel (insights/formula): 11 elements
|
386 |
_base_action_panel_ui_outputs = [
|
387 |
global_actions_column_ui, insights_chatbot_ui, insights_chatbot_ui,
|
388 |
insights_chat_input_ui, insights_suggestions_row_ui,
|
389 |
insights_suggestion_1_btn, insights_suggestion_2_btn, insights_suggestion_3_btn,
|
390 |
+
formula_display_markdown_ui, formula_display_markdown_ui, # Formula MD (vis + value)
|
391 |
+
formula_close_hint_md
|
392 |
]
|
393 |
+
# States for action panel: 4 elements
|
394 |
_action_panel_state_outputs = [active_panel_action_state, current_chat_plot_id_st, chat_histories_st, explored_plot_id_state]
|
395 |
|
396 |
+
action_panel_outputs_list = _base_action_panel_ui_outputs + _action_panel_state_outputs # 11 + 4 = 15
|
397 |
+
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("panel_component", gr.update()) for pc in plot_configs]) # +N (panels)
|
398 |
+
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("bomb_button", gr.update()) for pc in plot_configs]) # +N (bomb_button)
|
399 |
+
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("formula_button", gr.update()) for pc in plot_configs]) # +N (formula_button)
|
400 |
+
action_panel_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("explore_button", gr.update()) for pc in plot_configs]) # +N (explore_button)
|
401 |
+
action_panel_outputs_list.extend([section_titles_map.get(s_name, gr.update()) for s_name in unique_ordered_sections]) # +M (sections)
|
402 |
+
# Total for action_panel_outputs_list = 15 + 4N + M. For N=19, M=6: 15 + 76 + 6 = 97.
|
403 |
+
|
404 |
+
# Base UI/States for explore click: 4 elements
|
405 |
+
_explore_base_outputs = [explored_plot_id_state, global_actions_column_ui, active_panel_action_state, formula_close_hint_md]
|
406 |
+
explore_outputs_list = _explore_base_outputs # 4
|
407 |
+
explore_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("panel_component", gr.update()) for pc in plot_configs]) # +N (panels)
|
408 |
+
explore_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("explore_button", gr.update()) for pc in plot_configs]) # +N (explore_button)
|
409 |
+
explore_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("bomb_button", gr.update()) for pc in plot_configs]) # +N (bomb_button)
|
410 |
+
explore_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("formula_button", gr.update()) for pc in plot_configs]) # +N (formula_button)
|
411 |
+
explore_outputs_list.extend([section_titles_map.get(s_name, gr.update()) for s_name in unique_ordered_sections]) # +M (sections)
|
412 |
+
# Total for explore_outputs_list = 4 + 4N + M. For N=19, M=6: 4 + 76 + 6 = 86.
|
413 |
|
414 |
action_click_inputs = [active_panel_action_state, chat_histories_st, current_chat_plot_id_st, plot_data_for_chatbot_st, explored_plot_id_state]
|
415 |
explore_click_inputs = [explored_plot_id_state, active_panel_action_state]
|
|
|
441 |
plot_gen_results = update_analytics_plots_figures(current_token_state, date_filter_val, custom_start_val, custom_end_val, plot_configs)
|
442 |
status_msg, gen_figs, new_summaries = plot_gen_results[0], plot_gen_results[1:-1], plot_gen_results[-1]
|
443 |
|
444 |
+
all_updates = [status_msg] # 1
|
445 |
+
all_updates.extend(gen_figs if len(gen_figs) == len(plot_configs) else [create_placeholder_plot("Error", f"Fig missing {i}") for i in range(len(plot_configs))]) # +N (19)
|
446 |
+
|
447 |
+
# UI Resets (9 elements) + State Resets (4 elements) = 13 elements
|
448 |
+
all_updates.extend([
|
449 |
+
gr.update(visible=False), gr.update(value=[], visible=False), gr.update(value="", visible=False), # global_actions_col, chatbot, chat_input
|
450 |
+
gr.update(visible=False), gr.update(value="S1"), gr.update(value="S2"), gr.update(value="S3"), # suggestions_row, sugg_btns
|
451 |
+
gr.update(value="Formula details here.", visible=False), gr.update(visible=False), # formula_md, formula_hint_md
|
452 |
+
None, None, {}, new_summaries # active_panel_state, current_chat_plot_id, chat_histories, plot_data_for_chatbot
|
453 |
+
]) # +13
|
454 |
+
|
455 |
+
for _ in plot_configs: # Reset button icons (3) & panel visibility (1) = 4 per plot
|
456 |
+
all_updates.extend([gr.update(value=BOMB_ICON), gr.update(value=FORMULA_ICON), gr.update(value=EXPLORE_ICON), gr.update(visible=True)]) # +4N (76)
|
457 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
458 |
all_updates.append(None) # Reset explored_plot_id_state (1 element)
|
459 |
+
all_updates.extend([gr.update(visible=True)] * num_unique_sections) # Make all section titles visible (M = 6 elements)
|
460 |
+
# Total: 1 + N + 13 + 4N + 1 + M = 1 + 19 + 13 + 76 + 1 + 6 = 116. This matches apply_filter_and_sync_outputs_list.
|
461 |
logging.info(f"Prepared {len(all_updates)} updates for analytics refresh.")
|
462 |
return all_updates
|
463 |
|
464 |
+
# Construction of apply_filter_and_sync_outputs_list
|
465 |
+
# This list defines the components Gradio expects to be updated.
|
466 |
+
# Its length must match the number of items returned by refresh_all_analytics_ui_elements.
|
467 |
+
|
468 |
+
apply_filter_and_sync_outputs_list = [analytics_status_md] # 1. Status
|
469 |
+
apply_filter_and_sync_outputs_list.extend([plot_ui_objects.get(pc["id"], {}).get("plot_component", gr.update()) for pc in plot_configs]) # 2. Plot figures (N)
|
|
|
|
|
|
|
|
|
|
|
470 |
|
471 |
+
# 3. UI Resets (9 elements for action panel)
|
472 |
_ui_resets_for_filter = [
|
473 |
global_actions_column_ui, insights_chatbot_ui, insights_chat_input_ui,
|
474 |
insights_suggestions_row_ui, insights_suggestion_1_btn, insights_suggestion_2_btn, insights_suggestion_3_btn,
|
475 |
+
formula_display_markdown_ui, formula_close_hint_md
|
476 |
]
|
|
|
|
|
477 |
apply_filter_and_sync_outputs_list.extend(_ui_resets_for_filter)
|
478 |
+
|
479 |
+
# 4. State Resets (4 elements)
|
480 |
+
_state_resets_for_filter = [active_panel_action_state, current_chat_plot_id_st, chat_histories_st, plot_data_for_chatbot_st]
|
481 |
apply_filter_and_sync_outputs_list.extend(_state_resets_for_filter)
|
482 |
|
483 |
+
# 5. Plot-specific buttons (3 per plot) and panel visibility (1 per plot) = 4N elements
|
484 |
+
for pc in plot_configs:
|
485 |
pid = pc["id"]
|
486 |
apply_filter_and_sync_outputs_list.extend([
|
487 |
plot_ui_objects.get(pid, {}).get("bomb_button", gr.update()),
|
|
|
489 |
plot_ui_objects.get(pid, {}).get("explore_button", gr.update()),
|
490 |
plot_ui_objects.get(pid, {}).get("panel_component", gr.update())
|
491 |
])
|
492 |
+
|
493 |
+
# 6. Explored state reset (1 element)
|
494 |
+
apply_filter_and_sync_outputs_list.append(explored_plot_id_state)
|
495 |
+
|
496 |
+
# 7. Section Titles (M elements)
|
497 |
+
apply_filter_and_sync_outputs_list.extend([section_titles_map.get(s_name, gr.update()) for s_name in unique_ordered_sections])
|
498 |
+
# Total elements: 1 + N + 9 + 4 + 4N + 1 + M = 15 + 5N + M
|
499 |
+
# For N=19, M=6: 15 + 5*19 + 6 = 15 + 95 + 6 = 110 + 6 = 116. This is correct.
|
500 |
|
501 |
apply_filter_btn.click(
|
502 |
fn=refresh_all_analytics_ui_elements,
|