Spaces:
Build error
Build error
Ashkan Taghipour (The University of Western Australia) Claude Opus 4.6 commited on
Commit ·
1185c9e
1
Parent(s): 7ef3f1b
Replace broken multiselect with single-select + Add/Clear buttons
Browse filesGradio 6.5.1 multiselect dropdown is unreliable. Replaced with:
- Single-select dropdown to pick one line at a time
- "Add to party" button to add selected line to party list
- "Clear party" button to reset
- Visible "Party members" textbox showing current selections
This matches the backpack pattern used in Quest 2/4 which works reliably.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- app.py +27 -18
- ui/quest1.py +16 -7
app.py
CHANGED
|
@@ -156,31 +156,40 @@ with demo:
|
|
| 156 |
outputs=[C["q1_umap_plot"]],
|
| 157 |
)
|
| 158 |
|
| 159 |
-
# Party selection via
|
| 160 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
if state is None:
|
| 162 |
state = AppState()
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
state
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
if len(state.selected_party) > 10:
|
| 173 |
-
text += f" ... +{len(state.selected_party) - 10} more"
|
| 174 |
-
else:
|
| 175 |
-
text = "None selected"
|
| 176 |
-
return text, state
|
| 177 |
|
| 178 |
-
C["
|
| 179 |
-
fn=
|
| 180 |
inputs=[C["q1_party_dropdown"], C["state"]],
|
| 181 |
outputs=[C["q1_party_display"], C["state"]],
|
| 182 |
)
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
def on_compare_click(state):
|
| 185 |
fig, _ = on_compare_party(state, DATA)
|
| 186 |
return gr.Plot(value=fig, visible=True)
|
|
|
|
| 156 |
outputs=[C["q1_umap_plot"]],
|
| 157 |
)
|
| 158 |
|
| 159 |
+
# Party selection via add / clear buttons
|
| 160 |
+
def _party_display_text(party):
|
| 161 |
+
if party:
|
| 162 |
+
text = f"Selected {len(party)} lines: " + ", ".join(party[:10])
|
| 163 |
+
if len(party) > 10:
|
| 164 |
+
text += f" ... +{len(party) - 10} more"
|
| 165 |
+
return text
|
| 166 |
+
return "None selected"
|
| 167 |
+
|
| 168 |
+
def on_add_to_party(selected_line, state):
|
| 169 |
if state is None:
|
| 170 |
state = AppState()
|
| 171 |
+
if selected_line and selected_line not in state.selected_party:
|
| 172 |
+
state.selected_party.append(selected_line)
|
| 173 |
+
return _party_display_text(state.selected_party), state
|
| 174 |
+
|
| 175 |
+
def on_clear_party(state):
|
| 176 |
+
if state is None:
|
| 177 |
+
state = AppState()
|
| 178 |
+
state.selected_party = []
|
| 179 |
+
return "None selected", state
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
|
| 181 |
+
C["q1_add_party_btn"].click(
|
| 182 |
+
fn=on_add_to_party,
|
| 183 |
inputs=[C["q1_party_dropdown"], C["state"]],
|
| 184 |
outputs=[C["q1_party_display"], C["state"]],
|
| 185 |
)
|
| 186 |
|
| 187 |
+
C["q1_clear_party_btn"].click(
|
| 188 |
+
fn=on_clear_party,
|
| 189 |
+
inputs=[C["state"]],
|
| 190 |
+
outputs=[C["q1_party_display"], C["state"]],
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
def on_compare_click(state):
|
| 194 |
fig, _ = on_compare_party(state, DATA)
|
| 195 |
return gr.Plot(value=fig, visible=True)
|
ui/quest1.py
CHANGED
|
@@ -166,8 +166,8 @@ def build_quest1(line_choices: list[str] | None = None):
|
|
| 166 |
that ``layout.py`` can prefix them with ``q1_`` and ``app.py`` can
|
| 167 |
wire callbacks without changes.
|
| 168 |
|
| 169 |
-
Keys: tab, color_radio, umap_plot, party_dropdown,
|
| 170 |
-
compare_btn, comparison_plot
|
| 171 |
"""
|
| 172 |
with gr.Tab("Genetic Landscape", id="quest1") as tab:
|
| 173 |
|
|
@@ -221,11 +221,18 @@ def build_quest1(line_choices: list[str] | None = None):
|
|
| 221 |
with gr.Row():
|
| 222 |
party_dropdown = gr.Dropdown(
|
| 223 |
choices=line_choices or [],
|
| 224 |
-
label="
|
| 225 |
-
multiselect=True,
|
| 226 |
interactive=True,
|
| 227 |
filterable=True,
|
| 228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
)
|
| 230 |
compare_btn = gr.Button(
|
| 231 |
"Compare",
|
|
@@ -233,11 +240,11 @@ def build_quest1(line_choices: list[str] | None = None):
|
|
| 233 |
)
|
| 234 |
|
| 235 |
party_display = gr.Textbox(
|
| 236 |
-
label="
|
| 237 |
interactive=False,
|
| 238 |
value="None selected",
|
| 239 |
lines=1,
|
| 240 |
-
visible=
|
| 241 |
)
|
| 242 |
|
| 243 |
comparison_plot = gr.Plot(label="Comparison", visible=False)
|
|
@@ -262,6 +269,8 @@ def build_quest1(line_choices: list[str] | None = None):
|
|
| 262 |
"color_radio": color_radio,
|
| 263 |
"umap_plot": umap_plot,
|
| 264 |
"party_dropdown": party_dropdown,
|
|
|
|
|
|
|
| 265 |
"party_display": party_display,
|
| 266 |
"compare_btn": compare_btn,
|
| 267 |
"comparison_plot": comparison_plot,
|
|
|
|
| 166 |
that ``layout.py`` can prefix them with ``q1_`` and ``app.py`` can
|
| 167 |
wire callbacks without changes.
|
| 168 |
|
| 169 |
+
Keys: tab, color_radio, umap_plot, party_dropdown, add_party_btn,
|
| 170 |
+
clear_party_btn, party_display, compare_btn, comparison_plot
|
| 171 |
"""
|
| 172 |
with gr.Tab("Genetic Landscape", id="quest1") as tab:
|
| 173 |
|
|
|
|
| 221 |
with gr.Row():
|
| 222 |
party_dropdown = gr.Dropdown(
|
| 223 |
choices=line_choices or [],
|
| 224 |
+
label="Pick a line to add",
|
|
|
|
| 225 |
interactive=True,
|
| 226 |
filterable=True,
|
| 227 |
+
)
|
| 228 |
+
add_party_btn = gr.Button(
|
| 229 |
+
"Add to party",
|
| 230 |
+
variant="secondary",
|
| 231 |
+
)
|
| 232 |
+
clear_party_btn = gr.Button(
|
| 233 |
+
"Clear party",
|
| 234 |
+
variant="stop",
|
| 235 |
+
size="sm",
|
| 236 |
)
|
| 237 |
compare_btn = gr.Button(
|
| 238 |
"Compare",
|
|
|
|
| 240 |
)
|
| 241 |
|
| 242 |
party_display = gr.Textbox(
|
| 243 |
+
label="Party members",
|
| 244 |
interactive=False,
|
| 245 |
value="None selected",
|
| 246 |
lines=1,
|
| 247 |
+
visible=True,
|
| 248 |
)
|
| 249 |
|
| 250 |
comparison_plot = gr.Plot(label="Comparison", visible=False)
|
|
|
|
| 269 |
"color_radio": color_radio,
|
| 270 |
"umap_plot": umap_plot,
|
| 271 |
"party_dropdown": party_dropdown,
|
| 272 |
+
"add_party_btn": add_party_btn,
|
| 273 |
+
"clear_party_btn": clear_party_btn,
|
| 274 |
"party_display": party_display,
|
| 275 |
"compare_btn": compare_btn,
|
| 276 |
"comparison_plot": comparison_plot,
|