Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -303,26 +303,18 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
303 |
# Add button updates in a consistent order (e.g., order of plot_configs)
|
304 |
for cfg in plot_configs:
|
305 |
p_id = cfg["id"]
|
306 |
-
if p_id in plot_ui_objects:
|
307 |
-
# Append updates for bomb, explore, formula buttons for this plot_id
|
308 |
-
# Ensure explore button is handled by its own handler or reset here if needed
|
309 |
if plot_ui_objects[p_id]["bomb_button"] in button_updates:
|
310 |
final_updates.append(button_updates[plot_ui_objects[p_id]["bomb_button"]])
|
311 |
-
else:
|
312 |
final_updates.append(gr.update(value=BOMB_ICON))
|
313 |
|
314 |
-
# Explore button is handled separately, but ensure it's in the output list
|
315 |
-
# For now, we'll let its own handler manage its state, or reset it if another action occurs.
|
316 |
-
# This part needs careful thought for interactions between explore and other actions.
|
317 |
-
# Let's assume for now that activating insights/formula doesn't auto-close explore.
|
318 |
-
# We will need to add explore_button to the output list.
|
319 |
-
# For now, this handler focuses on insights/formula buttons.
|
320 |
-
# We'll need to expand the output list.
|
321 |
-
|
322 |
if plot_ui_objects[p_id]["formula_button"] in button_updates:
|
323 |
final_updates.append(button_updates[plot_ui_objects[p_id]["formula_button"]])
|
324 |
-
else:
|
325 |
final_updates.append(gr.update(value=FORMULA_ICON))
|
|
|
|
|
326 |
|
327 |
return final_updates
|
328 |
|
@@ -330,8 +322,8 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
330 |
def handle_explore_click(plot_id_clicked, current_explored_plot_id):
|
331 |
logging.info(f"Explore clicked for: {plot_id_clicked}. Currently explored: {current_explored_plot_id}")
|
332 |
|
333 |
-
panel_visibility_updates = {}
|
334 |
-
button_icon_updates = {}
|
335 |
new_explored_id = None
|
336 |
|
337 |
is_toggling_off = (plot_id_clicked == current_explored_plot_id)
|
@@ -343,98 +335,104 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
343 |
else:
|
344 |
new_explored_id = plot_id_clicked
|
345 |
button_icon_updates[plot_ui_objects[plot_id_clicked]["explore_button"]] = gr.update(value=ACTIVE_ICON)
|
346 |
-
# If another plot was explored, reset its button
|
347 |
if current_explored_plot_id and current_explored_plot_id != plot_id_clicked:
|
348 |
button_icon_updates[plot_ui_objects[current_explored_plot_id]["explore_button"]] = gr.update(value=EXPLORE_ICON)
|
349 |
logging.info(f"Exploring plot: {plot_id_clicked}")
|
350 |
|
351 |
-
# Determine visibility for all panels
|
352 |
for i in range(0, len(plot_configs), 2):
|
353 |
config1_id = plot_configs[i]["id"]
|
|
|
354 |
panel1 = plot_ui_objects[config1_id]["panel_component"]
|
355 |
|
356 |
-
show_panel1 =
|
357 |
-
if new_explored_id: # If any plot is explored
|
358 |
-
show_panel1 = (config1_id == new_explored_id)
|
359 |
panel_visibility_updates[panel1] = gr.update(visible=show_panel1)
|
360 |
|
361 |
if i + 1 < len(plot_configs):
|
362 |
config2_id = plot_configs[i+1]["id"]
|
363 |
-
|
|
|
364 |
if plot_configs[i+1]["section"] == plot_configs[i]["section"]:
|
365 |
panel2 = plot_ui_objects[config2_id]["panel_component"]
|
366 |
-
show_panel2 =
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
show_panel1 = False # Re-evaluate panel1 if panel2 is explored
|
374 |
-
panel_visibility_updates[panel1] = gr.update(visible=show_panel1)
|
375 |
-
|
376 |
-
|
377 |
panel_visibility_updates[panel2] = gr.update(visible=show_panel2)
|
378 |
-
# else: panel2 is in a new section, will be handled when its turn comes as config1_id
|
379 |
|
380 |
-
# Construct final updates list
|
381 |
-
# Order: explored_plot_id_state, then all panel visibility, then all explore button icons
|
382 |
final_updates = [new_explored_id]
|
383 |
for cfg in plot_configs:
|
384 |
p_id = cfg["id"]
|
385 |
if p_id in plot_ui_objects:
|
386 |
panel = plot_ui_objects[p_id]["panel_component"]
|
387 |
-
final_updates.append(panel_visibility_updates.get(panel, gr.update(
|
388 |
|
389 |
explore_btn = plot_ui_objects[p_id]["explore_button"]
|
390 |
-
final_updates.append(button_icon_updates.get(explore_btn, gr.update(value=EXPLORE_ICON
|
|
|
|
|
391 |
|
392 |
return final_updates
|
393 |
|
394 |
# --- Connect Action Buttons ---
|
395 |
-
# Outputs for Insights/Formula: global_actions_column_ui, global_actions_markdown_ui, active_panel_action_state, + all bomb_buttons, + all formula_buttons
|
396 |
action_buttons_outputs = [
|
397 |
global_actions_column_ui,
|
398 |
global_actions_markdown_ui,
|
399 |
active_panel_action_state
|
400 |
]
|
401 |
-
# Add all bomb and formula buttons to the output list for icon updates
|
402 |
for cfg in plot_configs:
|
403 |
pid = cfg["id"]
|
404 |
-
if pid in plot_ui_objects:
|
405 |
action_buttons_outputs.append(plot_ui_objects[pid]["bomb_button"])
|
406 |
action_buttons_outputs.append(plot_ui_objects[pid]["formula_button"])
|
407 |
-
|
408 |
-
|
|
|
409 |
explore_buttons_outputs = [explored_plot_id_state]
|
410 |
for cfg in plot_configs:
|
411 |
pid = cfg["id"]
|
412 |
-
if pid in plot_ui_objects:
|
413 |
explore_buttons_outputs.append(plot_ui_objects[pid]["panel_component"])
|
414 |
explore_buttons_outputs.append(plot_ui_objects[pid]["explore_button"])
|
|
|
|
|
415 |
|
416 |
|
417 |
for config_item in plot_configs:
|
418 |
plot_id = config_item["id"]
|
419 |
-
if plot_id in plot_ui_objects:
|
420 |
ui_obj = plot_ui_objects[plot_id]
|
421 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
422 |
ui_obj["bomb_button"].click(
|
423 |
-
fn=lambda p_id=plot_id: handle_panel_action(p_id, "insights", active_panel_action_state.value, token_state.value),
|
424 |
-
inputs=None,
|
425 |
-
outputs=
|
426 |
api_name=f"action_insights_{plot_id}"
|
427 |
)
|
428 |
ui_obj["formula_button"].click(
|
429 |
fn=lambda p_id=plot_id: handle_panel_action(p_id, "formula", active_panel_action_state.value, token_state.value),
|
430 |
inputs=None,
|
431 |
-
outputs=
|
432 |
api_name=f"action_formula_{plot_id}"
|
433 |
)
|
434 |
ui_obj["explore_button"].click(
|
435 |
fn=lambda p_id=plot_id: handle_explore_click(p_id, explored_plot_id_state.value),
|
436 |
inputs=None,
|
437 |
-
outputs=
|
438 |
api_name=f"action_explore_{plot_id}"
|
439 |
)
|
440 |
|
@@ -448,9 +446,8 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
448 |
status_message_update = plot_generation_results[0]
|
449 |
generated_plot_figures = plot_generation_results[1:]
|
450 |
|
451 |
-
all_updates = [status_message_update]
|
452 |
|
453 |
-
# Plot figure updates
|
454 |
for i, config in enumerate(plot_configs):
|
455 |
p_id_key = config["id"]
|
456 |
if p_id_key in plot_ui_objects:
|
@@ -459,43 +456,43 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
459 |
else:
|
460 |
all_updates.append(create_placeholder_plot("Figure Error", f"No figure for {p_id_key}"))
|
461 |
else:
|
462 |
-
all_updates.append(None)
|
463 |
|
464 |
-
# Reset Global Action Column
|
465 |
all_updates.append(gr.update(visible=False))
|
466 |
all_updates.append(gr.update(value="Click a button (💣, ƒ) on a plot..."))
|
467 |
-
all_updates.append(None)
|
468 |
|
469 |
-
# Reset all button icons (bomb, formula, explore) and panel visibility for explore
|
470 |
for cfg in plot_configs:
|
471 |
pid = cfg["id"]
|
472 |
if pid in plot_ui_objects:
|
473 |
-
all_updates.append(gr.update(value=BOMB_ICON))
|
474 |
-
all_updates.append(gr.update(value=FORMULA_ICON))
|
475 |
-
all_updates.append(gr.update(value=EXPLORE_ICON))
|
476 |
-
all_updates.append(gr.update(visible=True))
|
477 |
-
else:
|
478 |
all_updates.extend([None,None,None,None])
|
479 |
|
480 |
|
481 |
-
all_updates.append(None)
|
482 |
|
483 |
logging.info(f"Prepared {len(all_updates)} updates for analytics refresh.")
|
484 |
return all_updates
|
485 |
|
486 |
# --- Define outputs for the apply_filter_btn and sync.then() ---
|
487 |
apply_filter_and_sync_outputs = [analytics_status_md]
|
488 |
-
for config in plot_configs:
|
489 |
pid = config["id"]
|
490 |
-
|
|
|
|
|
|
|
491 |
|
492 |
-
apply_filter_and_sync_outputs.extend([
|
493 |
global_actions_column_ui,
|
494 |
global_actions_markdown_ui,
|
495 |
active_panel_action_state
|
496 |
])
|
497 |
|
498 |
-
# Add all button components and panel components for reset
|
499 |
for cfg in plot_configs:
|
500 |
pid = cfg["id"]
|
501 |
if pid in plot_ui_objects:
|
@@ -504,7 +501,9 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
|
|
504 |
apply_filter_and_sync_outputs.append(plot_ui_objects[pid]["explore_button"])
|
505 |
apply_filter_and_sync_outputs.append(plot_ui_objects[pid]["panel_component"])
|
506 |
else:
|
507 |
-
|
|
|
|
|
508 |
|
509 |
|
510 |
apply_filter_and_sync_outputs.append(explored_plot_id_state)
|
|
|
303 |
# Add button updates in a consistent order (e.g., order of plot_configs)
|
304 |
for cfg in plot_configs:
|
305 |
p_id = cfg["id"]
|
306 |
+
if p_id in plot_ui_objects: # Check if plot_id exists in UI objects
|
|
|
|
|
307 |
if plot_ui_objects[p_id]["bomb_button"] in button_updates:
|
308 |
final_updates.append(button_updates[plot_ui_objects[p_id]["bomb_button"]])
|
309 |
+
else:
|
310 |
final_updates.append(gr.update(value=BOMB_ICON))
|
311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
312 |
if plot_ui_objects[p_id]["formula_button"] in button_updates:
|
313 |
final_updates.append(button_updates[plot_ui_objects[p_id]["formula_button"]])
|
314 |
+
else:
|
315 |
final_updates.append(gr.update(value=FORMULA_ICON))
|
316 |
+
else: # Should not happen if plot_ui_objects is complete
|
317 |
+
final_updates.extend([gr.update(), gr.update()]) # Add empty updates to maintain length
|
318 |
|
319 |
return final_updates
|
320 |
|
|
|
322 |
def handle_explore_click(plot_id_clicked, current_explored_plot_id):
|
323 |
logging.info(f"Explore clicked for: {plot_id_clicked}. Currently explored: {current_explored_plot_id}")
|
324 |
|
325 |
+
panel_visibility_updates = {}
|
326 |
+
button_icon_updates = {}
|
327 |
new_explored_id = None
|
328 |
|
329 |
is_toggling_off = (plot_id_clicked == current_explored_plot_id)
|
|
|
335 |
else:
|
336 |
new_explored_id = plot_id_clicked
|
337 |
button_icon_updates[plot_ui_objects[plot_id_clicked]["explore_button"]] = gr.update(value=ACTIVE_ICON)
|
|
|
338 |
if current_explored_plot_id and current_explored_plot_id != plot_id_clicked:
|
339 |
button_icon_updates[plot_ui_objects[current_explored_plot_id]["explore_button"]] = gr.update(value=EXPLORE_ICON)
|
340 |
logging.info(f"Exploring plot: {plot_id_clicked}")
|
341 |
|
|
|
342 |
for i in range(0, len(plot_configs), 2):
|
343 |
config1_id = plot_configs[i]["id"]
|
344 |
+
if config1_id not in plot_ui_objects: continue # Skip if panel doesn't exist
|
345 |
panel1 = plot_ui_objects[config1_id]["panel_component"]
|
346 |
|
347 |
+
show_panel1 = not new_explored_id or (config1_id == new_explored_id)
|
|
|
|
|
348 |
panel_visibility_updates[panel1] = gr.update(visible=show_panel1)
|
349 |
|
350 |
if i + 1 < len(plot_configs):
|
351 |
config2_id = plot_configs[i+1]["id"]
|
352 |
+
if config2_id not in plot_ui_objects: continue # Skip if panel doesn't exist
|
353 |
+
|
354 |
if plot_configs[i+1]["section"] == plot_configs[i]["section"]:
|
355 |
panel2 = plot_ui_objects[config2_id]["panel_component"]
|
356 |
+
show_panel2 = not new_explored_id or (config2_id == new_explored_id)
|
357 |
+
|
358 |
+
if new_explored_id: # If a plot is being explored
|
359 |
+
if config1_id == new_explored_id: show_panel2 = False # Hide sibling if first is explored
|
360 |
+
elif config2_id == new_explored_id: show_panel1 = False # Hide sibling if second is explored
|
361 |
+
|
362 |
+
panel_visibility_updates[panel1] = gr.update(visible=show_panel1) # Re-update panel1 if changed
|
|
|
|
|
|
|
|
|
363 |
panel_visibility_updates[panel2] = gr.update(visible=show_panel2)
|
|
|
364 |
|
|
|
|
|
365 |
final_updates = [new_explored_id]
|
366 |
for cfg in plot_configs:
|
367 |
p_id = cfg["id"]
|
368 |
if p_id in plot_ui_objects:
|
369 |
panel = plot_ui_objects[p_id]["panel_component"]
|
370 |
+
final_updates.append(panel_visibility_updates.get(panel, gr.update(visible=not new_explored_id or (p_id == new_explored_id) )))
|
371 |
|
372 |
explore_btn = plot_ui_objects[p_id]["explore_button"]
|
373 |
+
final_updates.append(button_icon_updates.get(explore_btn, gr.update(value=EXPLORE_ICON if p_id != new_explored_id else ACTIVE_ICON)))
|
374 |
+
else: # Should not happen
|
375 |
+
final_updates.extend([gr.update(), gr.update()])
|
376 |
|
377 |
return final_updates
|
378 |
|
379 |
# --- Connect Action Buttons ---
|
|
|
380 |
action_buttons_outputs = [
|
381 |
global_actions_column_ui,
|
382 |
global_actions_markdown_ui,
|
383 |
active_panel_action_state
|
384 |
]
|
|
|
385 |
for cfg in plot_configs:
|
386 |
pid = cfg["id"]
|
387 |
+
if pid in plot_ui_objects: # Important check
|
388 |
action_buttons_outputs.append(plot_ui_objects[pid]["bomb_button"])
|
389 |
action_buttons_outputs.append(plot_ui_objects[pid]["formula_button"])
|
390 |
+
else: # Maintain list length if a plot_ui_object is unexpectedly missing
|
391 |
+
action_buttons_outputs.extend([None, None]) # This could cause issues if None is not handled by Gradio outputs
|
392 |
+
|
393 |
explore_buttons_outputs = [explored_plot_id_state]
|
394 |
for cfg in plot_configs:
|
395 |
pid = cfg["id"]
|
396 |
+
if pid in plot_ui_objects: # Important check
|
397 |
explore_buttons_outputs.append(plot_ui_objects[pid]["panel_component"])
|
398 |
explore_buttons_outputs.append(plot_ui_objects[pid]["explore_button"])
|
399 |
+
else: # Maintain list length
|
400 |
+
explore_buttons_outputs.extend([None, None])
|
401 |
|
402 |
|
403 |
for config_item in plot_configs:
|
404 |
plot_id = config_item["id"]
|
405 |
+
if plot_id in plot_ui_objects: # Ensure component exists before trying to attach event
|
406 |
ui_obj = plot_ui_objects[plot_id]
|
407 |
|
408 |
+
current_action_outputs = [
|
409 |
+
global_actions_column_ui,
|
410 |
+
global_actions_markdown_ui,
|
411 |
+
active_panel_action_state
|
412 |
+
] + [plot_ui_objects[c["id"]]["bomb_button"] for c in plot_configs if c["id"] in plot_ui_objects] \
|
413 |
+
+ [plot_ui_objects[c["id"]]["formula_button"] for c in plot_configs if c["id"] in plot_ui_objects]
|
414 |
+
|
415 |
+
current_explore_outputs = [explored_plot_id_state] \
|
416 |
+
+ [plot_ui_objects[c["id"]]["panel_component"] for c in plot_configs if c["id"] in plot_ui_objects] \
|
417 |
+
+ [plot_ui_objects[c["id"]]["explore_button"] for c in plot_configs if c["id"] in plot_ui_objects]
|
418 |
+
|
419 |
+
|
420 |
ui_obj["bomb_button"].click(
|
421 |
+
fn=lambda p_id=plot_id: handle_panel_action(p_id, "insights", active_panel_action_state.value, token_state.value),
|
422 |
+
inputs=None,
|
423 |
+
outputs=current_action_outputs, # Use dynamically scoped list
|
424 |
api_name=f"action_insights_{plot_id}"
|
425 |
)
|
426 |
ui_obj["formula_button"].click(
|
427 |
fn=lambda p_id=plot_id: handle_panel_action(p_id, "formula", active_panel_action_state.value, token_state.value),
|
428 |
inputs=None,
|
429 |
+
outputs=current_action_outputs, # Use dynamically scoped list
|
430 |
api_name=f"action_formula_{plot_id}"
|
431 |
)
|
432 |
ui_obj["explore_button"].click(
|
433 |
fn=lambda p_id=plot_id: handle_explore_click(p_id, explored_plot_id_state.value),
|
434 |
inputs=None,
|
435 |
+
outputs=current_explore_outputs, # Use dynamically scoped list
|
436 |
api_name=f"action_explore_{plot_id}"
|
437 |
)
|
438 |
|
|
|
446 |
status_message_update = plot_generation_results[0]
|
447 |
generated_plot_figures = plot_generation_results[1:]
|
448 |
|
449 |
+
all_updates = [status_message_update]
|
450 |
|
|
|
451 |
for i, config in enumerate(plot_configs):
|
452 |
p_id_key = config["id"]
|
453 |
if p_id_key in plot_ui_objects:
|
|
|
456 |
else:
|
457 |
all_updates.append(create_placeholder_plot("Figure Error", f"No figure for {p_id_key}"))
|
458 |
else:
|
459 |
+
all_updates.append(None)
|
460 |
|
|
|
461 |
all_updates.append(gr.update(visible=False))
|
462 |
all_updates.append(gr.update(value="Click a button (💣, ƒ) on a plot..."))
|
463 |
+
all_updates.append(None)
|
464 |
|
|
|
465 |
for cfg in plot_configs:
|
466 |
pid = cfg["id"]
|
467 |
if pid in plot_ui_objects:
|
468 |
+
all_updates.append(gr.update(value=BOMB_ICON))
|
469 |
+
all_updates.append(gr.update(value=FORMULA_ICON))
|
470 |
+
all_updates.append(gr.update(value=EXPLORE_ICON))
|
471 |
+
all_updates.append(gr.update(visible=True))
|
472 |
+
else:
|
473 |
all_updates.extend([None,None,None,None])
|
474 |
|
475 |
|
476 |
+
all_updates.append(None)
|
477 |
|
478 |
logging.info(f"Prepared {len(all_updates)} updates for analytics refresh.")
|
479 |
return all_updates
|
480 |
|
481 |
# --- Define outputs for the apply_filter_btn and sync.then() ---
|
482 |
apply_filter_and_sync_outputs = [analytics_status_md]
|
483 |
+
for config in plot_configs:
|
484 |
pid = config["id"]
|
485 |
+
if pid in plot_ui_objects and "plot_component" in plot_ui_objects[pid]:
|
486 |
+
apply_filter_and_sync_outputs.append(plot_ui_objects[pid]["plot_component"])
|
487 |
+
else:
|
488 |
+
apply_filter_and_sync_outputs.append(None) # Must add placeholder if component might be missing
|
489 |
|
490 |
+
apply_filter_and_sync_outputs.extend([
|
491 |
global_actions_column_ui,
|
492 |
global_actions_markdown_ui,
|
493 |
active_panel_action_state
|
494 |
])
|
495 |
|
|
|
496 |
for cfg in plot_configs:
|
497 |
pid = cfg["id"]
|
498 |
if pid in plot_ui_objects:
|
|
|
501 |
apply_filter_and_sync_outputs.append(plot_ui_objects[pid]["explore_button"])
|
502 |
apply_filter_and_sync_outputs.append(plot_ui_objects[pid]["panel_component"])
|
503 |
else:
|
504 |
+
# This case indicates a mismatch and will likely cause errors if not handled.
|
505 |
+
# Forcing list length for now, but root cause would be plot_ui_objects incompleteness.
|
506 |
+
apply_filter_and_sync_outputs.extend([None, None, None, None])
|
507 |
|
508 |
|
509 |
apply_filter_and_sync_outputs.append(explored_plot_id_state)
|