From d848cbd2af2a09a0d8a220e4c087938902392b37 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 14:38:20 +0200 Subject: [PATCH 01/12] adjust start page to have big buttons --- content/quickstart.py | 349 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 315 insertions(+), 34 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index 2e3de961..6c381e83 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -5,47 +5,328 @@ page_setup(page="main") -st.markdown("# ๐Ÿ‘‹ Quick Start") -st.markdown("## FLASHApp") - +def inject_workflow_button_css(): + """Inject CSS for custom workflow button styling with responsive design.""" + st.markdown( + """ + + """, + unsafe_allow_html=True, + ) -# main content -st.markdown('#### FLASHApp: A Platform for Your Favorite FLASH\* Tools!') +def create_workflow_button(emoji, title, subtitle, workflow_key, page_name): + """Create a workflow selection button with navigation.""" + button_html = f""" +
+
{emoji}
+
{title}
+
{subtitle}
+
+ """ + + if st.markdown(button_html, unsafe_allow_html=True): + return True + return False -st.info(""" - **๐Ÿ’ก How to run FLASHApp** - 1. Go to the **โš™๏ธ Workflow** page through the sidebar and run your analysis.\ - OR, go to the **๐Ÿ“ File Upload** page through the sidebar and upload FLASHDeconv output files (\*_annotated.mzML & \*_deconv.mzML) - 2. Click the **๐Ÿ‘€ Viewer** page on the sidebar to view the results in detail. - """) +def create_navigation_button(emoji, title, subtitle, page_path): + """Create a workflow button that navigates to the specified page.""" + button_html = f""" +
+
{emoji}
+
{title}
+
{subtitle}
+
+ """ + + # Display the styled button + st.markdown(button_html, unsafe_allow_html=True) + + # Create a button for navigation + if st.button(f"Start {title}", key=f"{title.lower()}_nav_btn", use_container_width=True, type="primary"): + st.switch_page(page_path) -if Path("OpenMS-App.zip").exists(): - st.subheader( +def render_workflow_selection(): + """Render the main workflow selection section.""" + # Hero section + st.markdown( """ -Download the latest version for Windows here by clicking the button below. -""" +
+

๐Ÿ‘‹ Quick Start

+

FLASHApp: Choose Your Analysis Workflow

+
+ """, + unsafe_allow_html=True, ) - with open("OpenMS-App.zip", "rb") as file: - st.download_button( - label="Download for Windows", - data=file, - file_name="OpenMS-App.zip", - mime="archive/zip", - type="primary", + + # Main workflow selection buttons in 3-column layout + col1, col2, col3 = st.columns(3) + + with col1: + create_navigation_button( + "โšก๏ธ", + "Deconvolution", + "FLASHDeconv", + "content/FLASHDeconv/FLASHDeconvWorkflow.py" + ) + + with col2: + create_navigation_button( + "๐Ÿงจ", + "Identification", + "FLASHTnT", + "content/FLASHTnT/FLASHTnTWorkflow.py" ) + + with col3: + create_navigation_button( + "๐Ÿ“Š", + "Quantification", + "FLASHQuant", + "content/FLASHQuant/FLASHQuantFileUpload.py" + ) + +def render_enhanced_download_section(): + """Render the enhanced Windows download section.""" + if Path("OpenMS-App.zip").exists(): + st.markdown( + """ +
+

๐ŸชŸ Download for Windows

+

Get the standalone Windows application for offline use

+
+ """, + unsafe_allow_html=True, + ) + + # Center the download button + col1, col2, col3 = st.columns([1, 2, 1]) + with col2: + with open("OpenMS-App.zip", "rb") as file: + st.download_button( + label="๐Ÿ“ฅ Download for Windows", + data=file, + file_name="OpenMS-App.zip", + mime="archive/zip", + type="primary", + use_container_width=True, + ) + + st.markdown( + """ +
+ Extract the zip file and run the installer (.msi) to install the app.
+ Launch using the desktop icon after installation. +
+ """, + unsafe_allow_html=True, + ) + +def render_footer(): + """Render the footer section with new features and OpenMS logo.""" st.markdown( """ -Extract the zip file and run the installer (.msi) file to install the app. The app can then be launched using the corresponding desktop icon. -""" + ", unsafe_allow_html=True) -c1, c2 = st.columns(2) -c1.markdown( - """ -## โญ New - -- FLASHViewer is now FLASHApp -- Want to save your progress or share it with your team? Simply bookmark / share the URL! -""" -) -c2.image("assets/OpenMS.png", width=300) +# Main execution +def main(): + """Main function to render the quickstart page.""" + # Inject custom CSS + inject_workflow_button_css() + + # Render main sections + render_workflow_selection() + + v_space(2) + + render_enhanced_download_section() + + render_footer() + +# Execute main function +if __name__ == "__main__": + main() +else: + main() From 3bed97a0b9c5968fe8c820b8033657b4d84cea98 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 14:53:24 +0200 Subject: [PATCH 02/12] styling --- content/quickstart.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/content/quickstart.py b/content/quickstart.py index 6c381e83..af33f2f1 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -37,18 +37,43 @@ def inject_workflow_button_css(): box-shadow: 0 8px 24px rgba(41, 55, 155, 0.3); } + .workflow-button:active { + background: linear-gradient(135deg, #1e2a7a 0%, #162159 100%); + border-color: #1e2a7a; + color: white !important; + transform: translateY(-2px) scale(0.98); + box-shadow: 0 4px 12px rgba(41, 55, 155, 0.4); + } + + .workflow-button:focus { + outline: 3px solid #29379b; + outline-offset: 2px; + } + .workflow-button:hover .workflow-emoji { transform: scale(1.1); } + .workflow-button:active .workflow-emoji { + transform: scale(1.05); + } + .workflow-button:hover .workflow-title { color: white !important; } + .workflow-button:active .workflow-title { + color: white !important; + } + .workflow-button:hover .workflow-subtitle { color: #e9ecef !important; } + .workflow-button:active .workflow-subtitle { + color: #e9ecef !important; + } + .workflow-emoji { font-size: 3.5rem; margin-bottom: 1rem; From 69ebc9ac53f61d54992abf7375fd17d098cc090f Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 16:11:35 +0200 Subject: [PATCH 03/12] remove duplicate styling --- content/quickstart.py | 131 +++++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 26 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index af33f2f1..dc15d940 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -190,36 +190,115 @@ def inject_workflow_button_css(): unsafe_allow_html=True, ) -def create_workflow_button(emoji, title, subtitle, workflow_key, page_name): - """Create a workflow selection button with navigation.""" - button_html = f""" -
-
{emoji}
-
{title}
-
{subtitle}
-
- """ - - if st.markdown(button_html, unsafe_allow_html=True): - return True - return False - def create_navigation_button(emoji, title, subtitle, page_path): - """Create a workflow button that navigates to the specified page.""" - button_html = f""" -
-
{emoji}
-
{title}
-
{subtitle}
-
- """ + """Create a functional workflow button that navigates to the specified page.""" - # Display the styled button - st.markdown(button_html, unsafe_allow_html=True) + # Create unique key for this button + button_key = f"{title.lower().replace(' ', '_')}_nav_btn" - # Create a button for navigation - if st.button(f"Start {title}", key=f"{title.lower()}_nav_btn", use_container_width=True, type="primary"): + # Create the button with custom styling applied via CSS classes + button_label = f"{emoji} {title}" + + # Use Streamlit's button with custom styling + if st.button( + label=button_label, + key=button_key, + help=f"Navigate to {title} - {subtitle}", + use_container_width=True, + type="primary" + ): st.switch_page(page_path) + + # Apply custom CSS styling using the key-based selector approach + st.markdown( + f""" + + """, + unsafe_allow_html=True, + ) def render_workflow_selection(): """Render the main workflow selection section.""" From 0f17b20b7d90c76df5ec770d71e56d9f2ce4c228 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 16:26:53 +0200 Subject: [PATCH 04/12] enable autoscaling --- content/quickstart.py | 118 +++++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 37 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index dc15d940..3d012840 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -19,7 +19,7 @@ def inject_workflow_button_css(): text-align: center; cursor: pointer; transition: all 0.3s ease; - height: 240px; + height: max(280px, 20vh); display: flex; flex-direction: column; justify-content: center; @@ -75,21 +75,21 @@ def inject_workflow_button_css(): } .workflow-emoji { - font-size: 3.5rem; - margin-bottom: 1rem; + font-size: clamp(2.5rem, 4vw, 5rem); + margin-bottom: clamp(0.75rem, 1.5vh, 1.5rem); transition: transform 0.3s ease; } .workflow-title { - font-size: 1.5rem; + font-size: clamp(1.25rem, 2.5vw, 2rem); font-weight: 700; color: #29379b; - margin-bottom: 0.5rem; + margin-bottom: clamp(0.375rem, 0.75vh, 0.75rem); transition: color 0.3s ease; } .workflow-subtitle { - font-size: 1rem; + font-size: clamp(0.875rem, 1.5vw, 1.25rem); color: #6c757d; font-weight: 500; transition: color 0.3s ease; @@ -138,24 +138,44 @@ def inject_workflow_button_css(): border-top: 1px solid #dee2e6; } - /* Responsive design */ - @media (max-width: 768px) { + /* Responsive design with dynamic scaling */ + + /* Wide screens (> 1440px) - Maximum size */ + @media (min-width: 1441px) { .workflow-button { - height: 200px; - padding: 1.5rem 1rem; - margin-bottom: 1rem; + height: max(400px, 25vh); + padding: clamp(2.5rem, 3vw, 4rem) clamp(2rem, 2.5vw, 3rem); + max-width: 500px; + margin: 0 auto 1.5rem auto; } - - .workflow-emoji { - font-size: 2.5rem; + } + + /* Desktop (1024px - 1440px) - Significantly larger */ + @media (min-width: 1024px) and (max-width: 1440px) { + .workflow-button { + height: max(320px, 22vh); + padding: clamp(2rem, 2.5vw, 3rem) clamp(1.75rem, 2vw, 2.5rem); + max-width: 450px; + margin: 0 auto 1.25rem auto; } - - .workflow-title { - font-size: 1.25rem; + } + + /* Tablet (768px - 1023px) - Slightly larger */ + @media (min-width: 768px) and (max-width: 1023px) { + .workflow-button { + height: max(260px, 18vh); + padding: clamp(1.75rem, 2vw, 2.5rem) clamp(1.5rem, 1.75vw, 2rem); + max-width: 400px; + margin: 0 auto 1rem auto; } - - .workflow-subtitle { - font-size: 0.9rem; + } + + /* Mobile landscape (481px - 767px) - Moderate size */ + @media (min-width: 481px) and (max-width: 767px) { + .workflow-button { + height: max(240px, 16vh); + padding: 1.5rem 1.25rem; + margin-bottom: 1rem; } .hero-title { @@ -167,23 +187,46 @@ def inject_workflow_button_css(): } } + /* Mobile portrait (โ‰ค 480px) - Compact size */ @media (max-width: 480px) { .workflow-button { - height: 180px; - padding: 1rem; - } - - .workflow-emoji { - font-size: 2rem; - } - - .workflow-title { - font-size: 1.1rem; + height: max(200px, 14vh); + padding: 1.25rem 1rem; + margin-bottom: 1rem; } .hero-title { font-size: 1.75rem; } + + .hero-subtitle { + font-size: 1rem; + } + } + + /* Optimize column spacing for workflow buttons */ + .main .block-container [data-testid="column"] { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + + /* Ensure first and last columns have proper edge spacing */ + .main .block-container [data-testid="column"]:first-child { + padding-left: 0 !important; + } + + .main .block-container [data-testid="column"]:last-child { + padding-right: 0 !important; + } + + /* Reduce button margins for tighter layout */ + .workflow-button { + margin-bottom: 0.5rem !important; + } + + /* Container spacing optimization */ + .stColumn > div { + padding-top: 0 !important; } """, @@ -219,13 +262,13 @@ def create_navigation_button(emoji, title, subtitle, page_path): border: 2px solid #dee2e6 !important; border-radius: 12px !important; padding: 2rem 1.5rem !important; - height: 240px !important; - min-height: 240px !important; + height: max(280px, 20vh) !important; + min-height: max(280px, 20vh) !important; box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important; transition: all 0.3s ease !important; margin-bottom: 1rem !important; color: #29379b !important; - font-size: 1.5rem !important; + font-size: clamp(1.25rem, 2.5vw, 2rem) !important; font-weight: 700 !important; display: flex !important; flex-direction: column !important; @@ -238,7 +281,7 @@ def create_navigation_button(emoji, title, subtitle, page_path): .st-key-{button_key} button p {{ color: #29379b !important; - font-size: 1.5rem !important; + font-size: clamp(1.25rem, 2.5vw, 2rem) !important; font-weight: 700 !important; margin: 0 !important; }} @@ -278,7 +321,7 @@ def create_navigation_button(emoji, title, subtitle, page_path): .st-key-{button_key} button::after {{ content: "{subtitle}"; display: block; - font-size: 1rem !important; + font-size: clamp(0.875rem, 1.5vw, 1.25rem) !important; font-weight: 500 !important; color: #6c757d !important; margin-top: 0.5rem !important; @@ -313,8 +356,9 @@ def render_workflow_selection(): unsafe_allow_html=True, ) - # Main workflow selection buttons in 3-column layout - col1, col2, col3 = st.columns(3) + # Main workflow selection buttons with centered, compact layout + # Use spacing columns to center buttons and prevent wide-screen spreading + spacer1, col1, col2, col3, spacer2 = st.columns([1, 2, 2, 2, 1], gap="small") with col1: create_navigation_button( From b7cd8a973d9494a67c655ebc8abe2043007355a7 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 16:37:11 +0200 Subject: [PATCH 05/12] update header --- content/quickstart.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index 3d012840..36187c93 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -345,17 +345,31 @@ def create_navigation_button(emoji, title, subtitle, page_path): def render_workflow_selection(): """Render the main workflow selection section.""" - # Hero section + # Hero section with title on left and OpenMS logo on right st.markdown( """
-

๐Ÿ‘‹ Quick Start

-

FLASHApp: Choose Your Analysis Workflow

-
""", unsafe_allow_html=True, ) + # Create columns for title and logo + spacer1, title_col, logo_col, spacer2 = st.columns([1, 4.5, 1.5, 1]) + + with title_col: + st.markdown( + """ +

๐Ÿ‘‹ FLASHApp

+

A platform for your favourite FLASH Tools!

+ """, + unsafe_allow_html=True, + ) + + with logo_col: + st.image("assets/OpenMS.png", width=200) + + st.markdown("", unsafe_allow_html=True) + # Main workflow selection buttons with centered, compact layout # Use spacing columns to center buttons and prevent wide-screen spreading spacer1, col1, col2, col3, spacer2 = st.columns([1, 2, 2, 2, 1], gap="small") From 8bbf1044987e02cadf3466696f6969396c7b0705 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 16:43:06 +0200 Subject: [PATCH 06/12] minor styling --- content/quickstart.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index 36187c93..ea57dce6 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -481,14 +481,9 @@ def main(): # Render main sections render_workflow_selection() - v_space(2) render_enhanced_download_section() render_footer() -# Execute main function -if __name__ == "__main__": - main() -else: - main() +main() From 83f67d4b69de74e46c1f32bee5c0da33f52269fb Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 17:03:26 +0200 Subject: [PATCH 07/12] make offline mode less prominent --- content/quickstart.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index ea57dce6..805e423a 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -399,28 +399,41 @@ def render_workflow_selection(): ) def render_enhanced_download_section(): - """Render the enhanced Windows download section.""" if Path("OpenMS-App.zip").exists(): + # Add spacing + st.markdown("


", unsafe_allow_html=True) + st.markdown( """ -
-

๐ŸชŸ Download for Windows

-

Get the standalone Windows application for offline use

+
+

+ Want to use FLASHApp offline? +

+

+ FLASHApp is best enjoyed online but you can download an offline version for Windows systems below. +

""", unsafe_allow_html=True, ) - # Center the download button - col1, col2, col3 = st.columns([1, 2, 1]) + # Center the download button with smaller size + col1, col2, col3 = st.columns([2, 2, 2]) with col2: with open("OpenMS-App.zip", "rb") as file: st.download_button( - label="๐Ÿ“ฅ Download for Windows", + label="๐Ÿ“ฅ Download ZIP", data=file, file_name="OpenMS-App.zip", mime="archive/zip", - type="primary", + type="secondary", use_container_width=True, ) From 181d1832fea8f7ce188774373ed496f9c362f01c Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 17:14:13 +0200 Subject: [PATCH 08/12] finalize quickstart --- content/quickstart.py | 126 ++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 73 deletions(-) diff --git a/content/quickstart.py b/content/quickstart.py index 805e423a..267eed2c 100644 --- a/content/quickstart.py +++ b/content/quickstart.py @@ -403,87 +403,68 @@ def render_enhanced_download_section(): # Add spacing st.markdown("


", unsafe_allow_html=True) - st.markdown( - """ -
+ # Create Streamlit container with key for styling (similar to button approach) + container_key = "windows_download_container" + + with st.container(key=container_key): + st.markdown( + """

Want to use FLASHApp offline?

-

+

FLASHApp is best enjoyed online but you can download an offline version for Windows systems below.

-
- """, - unsafe_allow_html=True, - ) - - # Center the download button with smaller size - col1, col2, col3 = st.columns([2, 2, 2]) - with col2: - with open("OpenMS-App.zip", "rb") as file: - st.download_button( - label="๐Ÿ“ฅ Download ZIP", - data=file, - file_name="OpenMS-App.zip", - mime="archive/zip", - type="secondary", - use_container_width=True, - ) - - st.markdown( - """ -
- Extract the zip file and run the installer (.msi) to install the app.
- Launch using the desktop icon after installation. -
- """, - unsafe_allow_html=True, - ) - -def render_footer(): - """Render the footer section with new features and OpenMS logo.""" - st.markdown( - """ - ", unsafe_allow_html=True) # Main execution def main(): @@ -497,6 +478,5 @@ def main(): render_enhanced_download_section() - render_footer() main() From e4ef45c939a811ec43b33cb3e93f1d30194b0928 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Sun, 10 Aug 2025 18:49:05 +0200 Subject: [PATCH 09/12] fix float display --- src/workflow/StreamlitUI.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/workflow/StreamlitUI.py b/src/workflow/StreamlitUI.py index a8f7cf51..bb76e9d3 100644 --- a/src/workflow/StreamlitUI.py +++ b/src/workflow/StreamlitUI.py @@ -749,6 +749,7 @@ def display_TOPP_params(params: dict, num_cols): value=float(p["value"]), step=1.0, help=p["description"], + format="%0.5f", key=key, ) From fda9a838a37f0f45488fda81a7ac1b58819ec450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20David=20M=C3=BCller?= <57191390+t0mdavid-m@users.noreply.github.com> Date: Sun, 10 Aug 2025 19:29:23 +0200 Subject: [PATCH 10/12] pin autowrap --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5f5caebc..362d4592 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,7 +80,7 @@ SHELL ["mamba", "run", "-n", "streamlit-env", "/bin/bash", "-c"] # Install up-to-date cmake via mamba and packages for pyOpenMS build. RUN mamba install cmake -RUN pip install --upgrade pip && python -m pip install -U setuptools nose 'Cython<3.1' autowrap pandas 'numpy==1.26.4' pytest +RUN pip install --upgrade pip && python -m pip install -U setuptools nose 'Cython<3.1' 'autowrap<0.23' pandas 'numpy==1.26.4' pytest # Clone OpenMS branch and the associcated contrib+thirdparties+pyOpenMS-doc submodules. RUN git clone --recursive --depth=1 -b ${OPENMS_BRANCH} --single-branch ${OPENMS_REPO} && cd /OpenMS From 9a87fcfbffa54d77726677bb5fa6755c96a47f45 Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Mon, 11 Aug 2025 08:12:53 +0200 Subject: [PATCH 11/12] fix Z handling --- src/render/sequence.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/sequence.py b/src/render/sequence.py index 48b83bc5..5cb0b4e2 100644 --- a/src/render/sequence.py +++ b/src/render/sequence.py @@ -166,7 +166,8 @@ def getFragmentDataFromSeq(sequence, coverage=None, maxCoverage=None, modificati 'W': 186.079313, 'Y': 163.063329, 'V': 99.068414, - 'X' : 0 + 'X' : 0, + 'Z' : 0, # Glx does not have defined mass } def isMatchWithTolerance(A, t, s): From 866301b6dafbc1b286405569a3653fb2b7ba057d Mon Sep 17 00:00:00 2001 From: Tom David Mueller Date: Mon, 11 Aug 2025 08:14:10 +0200 Subject: [PATCH 12/12] bump version --- .github/workflows/build-windows-executable-app.yaml | 2 +- settings.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-windows-executable-app.yaml b/.github/workflows/build-windows-executable-app.yaml index feb31e08..4f6494d6 100644 --- a/.github/workflows/build-windows-executable-app.yaml +++ b/.github/workflows/build-windows-executable-app.yaml @@ -14,7 +14,7 @@ env: OPENMS_VERSION: 3.2.0 PYTHON_VERSION: 3.11.0 # Name of the installer - APP_NAME: FLASHApp-0.8.4 + APP_NAME: FLASHApp-0.9.0 APP_UpgradeCode: "69ae44ad-d554-4e3c-8715-7c4daf60f8bb" jobs: diff --git a/settings.json b/settings.json index 58bbb506..6d2f884e 100644 --- a/settings.json +++ b/settings.json @@ -1,7 +1,7 @@ { "app-name": "FLASHApp", "github-user": "OpenMS", - "version": "0.8.4", + "version": "0.9.0", "repository-name": "FLASHApp", "analytics": { "google-analytics": {