Skip to content

Commit fe4b506

Browse files
committed
fix: export data button duplication
1 parent b2c37a1 commit fe4b506

1 file changed

Lines changed: 69 additions & 51 deletions

File tree

src/ui/export_view.py

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def _generate_csv_data(filtered_df: pd.DataFrame) -> bytes | None:
250250
def render_export_section(filtered_ef_df: pd.DataFrame) -> None:
251251
"""
252252
Renders the export section, allowing users to download selected files
253-
as a ZIP archive.
253+
as a ZIP archive using a state-driven UI to prevent widget duplication.
254254
255255
Args:
256256
filtered_ef_df (pd.DataFrame): DataFrame filtered by all previous selections.
@@ -261,70 +261,88 @@ def render_export_section(filtered_ef_df: pd.DataFrame) -> None:
261261
st.info("No EyeFlow data is selected to be exported.")
262262
return
263263

264-
st.subheader("Create an export package")
265-
col1, col2 = st.columns(2)
264+
# Initialize state if it doesn't exist
265+
if "export_status" not in st.session_state:
266+
st.session_state.export_status = "ready_to_export"
266267

267-
with col1:
268-
if st.button("Export pdf reports + csv data", use_container_width=True):
269-
# Clear previous zip from session state to avoid showing old downloads
270-
if "zip_buffer" in st.session_state:
271-
del st.session_state["zip_buffer"]
268+
# --- STATE 3: Ready to Download ---
269+
# If a zip file has been created, show the download button.
270+
if st.session_state.export_status == "ready_to_download":
271+
st.success("Your export package is ready to be downloaded.")
272+
st.download_button(
273+
label="Download ZIP",
274+
data=st.session_state.zip_buffer.getvalue(),
275+
file_name=st.session_state.get("zip_file_name", "eyeflow_export.zip"),
276+
mime="application/zip",
277+
on_click=lambda: st.session_state.update(export_status="ready_to_export"),
278+
)
279+
if st.session_state.get("skipped_files"):
280+
st.warning("The following files were not found and were skipped:")
281+
st.code("\n".join(st.session_state.get("skipped_files", [])))
272282

283+
# --- STATE 2: Processing ---
284+
# If an export has been triggered, run the zipping process.
285+
# The buttons from the 'else' block will NOT be rendered.
286+
elif st.session_state.export_status == "processing":
287+
export_type = st.session_state.get("export_type", "full")
288+
289+
# Determine which files to collect based on the button clicked
290+
if export_type == "pdf_csv":
273291
files_to_zip = _collect_files_to_zip(
274292
filtered_ef_df,
275293
export_pdfs=True,
276294
export_h5s=False,
277295
export_jsons=False,
278296
export_input_params=False,
279297
)
280-
csv_data = _generate_csv_data(filtered_ef_df)
281-
282-
if not files_to_zip and not csv_data:
283-
st.warning("No PDF reports or CSV data are available to export.")
284-
else:
285-
zip_buffer, skipped_files = _create_zip_archive(files_to_zip, csv_data)
286-
st.session_state.zip_buffer = zip_buffer
287-
st.session_state.skipped_files = skipped_files
288-
st.session_state.zip_file_name = "eyeflow_pdf_csv_export.zip"
289-
290-
with col2:
291-
if st.button(
292-
"Export all (pdf reports, csv data, h5 outputs, json outputs and params)",
293-
use_container_width=True,
294-
):
295-
# Clear previous zip from session state
296-
if "zip_buffer" in st.session_state:
297-
del st.session_state["zip_buffer"]
298-
298+
st.session_state.zip_file_name = "eyeflow_pdf_csv_export.zip"
299+
else: # 'full' export
299300
files_to_zip = _collect_files_to_zip(
300301
filtered_ef_df,
301302
export_pdfs=True,
302303
export_h5s=True,
303304
export_jsons=True,
304305
export_input_params=True,
305306
)
306-
csv_data = _generate_csv_data(filtered_ef_df)
307+
st.session_state.zip_file_name = "eyeflow_full_export.zip"
307308

308-
if not files_to_zip and not csv_data:
309-
st.warning("No files or data are available to export.")
310-
else:
311-
zip_buffer, skipped_files = _create_zip_archive(files_to_zip, csv_data)
312-
st.session_state.zip_buffer = zip_buffer
313-
st.session_state.skipped_files = skipped_files
314-
st.session_state.zip_file_name = "eyeflow_full_export.zip"
315-
316-
# --- Download Section ---
317-
# This part remains active as long as a zip_buffer is in the session state
318-
if "zip_buffer" in st.session_state:
319-
st.success("Your export package is ready to be downloaded.")
320-
st.download_button(
321-
label="Download ZIP",
322-
data=st.session_state.zip_buffer.getvalue(),
323-
file_name=st.session_state.get("zip_file_name", "eyeflow_export.zip"),
324-
mime="application/zip",
325-
# Remove the buffer from state after clicking download
326-
on_click=lambda: st.session_state.pop("zip_buffer", None),
327-
)
328-
if st.session_state.get("skipped_files"):
329-
st.warning("The following files were not found and were skipped:")
330-
st.code("\n".join(st.session_state.get("skipped_files", [])))
309+
csv_data = _generate_csv_data(filtered_ef_df)
310+
311+
if not files_to_zip and not csv_data:
312+
st.warning("No files or data are available to export.")
313+
st.session_state.export_status = "ready_to_export" # Reset state
314+
st.rerun()
315+
else:
316+
zip_buffer, skipped_files = _create_zip_archive(files_to_zip, csv_data)
317+
st.session_state.zip_buffer = zip_buffer
318+
st.session_state.skipped_files = skipped_files
319+
320+
# Transition to the next state and rerun
321+
st.session_state.export_status = "ready_to_download"
322+
st.rerun()
323+
324+
# --- STATE 1: Ready to Export (Default) ---
325+
# Otherwise, show the export buttons.
326+
else:
327+
st.subheader("Create an export package")
328+
col1, col2 = st.columns(2)
329+
330+
def set_export_type(export_type: str):
331+
st.session_state.export_status = "processing"
332+
st.session_state.export_type = export_type
333+
334+
with col1:
335+
st.button(
336+
"Export pdf reports + csv data",
337+
use_container_width=True,
338+
on_click=set_export_type,
339+
args=("pdf_csv",),
340+
)
341+
342+
with col2:
343+
st.button(
344+
"Export all (pdf reports, csv data, h5 outputs, json outputs and params)",
345+
use_container_width=True,
346+
on_click=set_export_type,
347+
args=("full",),
348+
)

0 commit comments

Comments
 (0)