Skip to content

feat(advanced-options): Set up advanced options panel for subnetwork search#178

Open
tonywu1999 wants to merge 7 commits intodevelfrom
feature-advanced-options
Open

feat(advanced-options): Set up advanced options panel for subnetwork search#178
tonywu1999 wants to merge 7 commits intodevelfrom
feature-advanced-options

Conversation

@tonywu1999
Copy link
Contributor

@tonywu1999 tonywu1999 commented Mar 5, 2026

Motivation and Context

This PR adds a collapsible "Advanced Options" panel to the network visualization module so users can refine subnetwork extraction. The UI exposes three new filters — PTM-site matching, inclusion of infinite fold-changes, and regulation direction — and these inputs are threaded through the server to MSstatsBioNet::getSubnetworkFromIndra and into the generated reproducible code. The change enables more precise, PTM-aware network extraction and ensures the advanced options are captured in exported code.

Detailed Changes

  • NAMESPACE / package imports

    • Added importFrom(shiny, actionLink).
    • Added importFrom(shinyjs, toggle) and updated roxygen import in R/MSstatsShiny.R to include shinyjs::toggle.
  • UI module (R/module-visualize-network-ui.R)

    • Added createAdvancedOptionsCollapsible(ns):
      • Action link ns("toggle_adv") to toggle visibility.
      • Hidden panel (shinyjs::hidden) containing:
        • checkboxInput ns("filterByCuration") (existing, moved inside panel)
        • checkboxInput ns("filter_by_ptm_site") — new
        • checkboxInput ns("include_infinite_fc") — new
        • selectInput ns("direction") — new: "both"/"up"/"down"
      • useShinyjs() called in helper (module-level useShinyjs() still present).
    • Replaced createCurationFilterCheckbox(...) with createAdvancedOptionsCollapsible(ns) in createDataUploadBox().
    • UI changes reported: +62 / -12 lines.
  • Server module and helpers (R/module-visualize-network-server.R, R/MSstatsShiny.R)

    • getInputParameters now returns filter_by_ptm_site, include_infinite_fc, direction alongside existing parameters.
    • extractSubnetwork(...) signature extended to include filter_by_ptm_site, include_infinite_fc, direction and passes them to MSstatsBioNet::getSubnetworkFromIndra.
    • visualizeNetworkServer observes input$toggle_adv and uses shinyjs::toggle() to show/hide the advanced panel.
    • Generated code blocks and code export now include the new parameters so reproducible code reflects user choices.
    • Server changes reported: lines increased and wiring of parameters through the flow implemented.
  • Tests (tests/testthat/test_network_visualization.R)

    • Updated tests to use Mockito-style mock(expected_subnetwork) and stub getSubnetworkFromIndra.
    • Modified extractSubnetwork test calls and mocks to accept and verify new parameters: filter_by_ptm_site = FALSE, include_infinite_fc = FALSE, direction = "both".
    • Assertions added to verify the mock was called once with the expected arguments.

Unit tests added/modified

  • tests/testthat/test_network_visualization.R:
    • Extended mocked extractSubnetwork/getSubnetworkFromIndra usage to accept the three new parameters and asserted they are forwarded correctly.
    • No new tests added that exercise:
      • UI toggle behavior (input$toggle_adv / shinyjs toggle).
      • Functional effects of filter_by_ptm_site, include_infinite_fc, or direction on actual subnetwork results (tests only verify delegation/argument forwarding via mocks).
      • Explicit default/null coercion behavior for the new inputs in varied contexts.

Coding guidelines / potential issues

  1. Test coverage gaps:

    • No behavioral tests validate the actual effect of the new parameters on subnetwork results or the UI toggle behavior; coverage is limited to signature/argument forwarding.
  2. Input default/null handling inconsistency:

    • getInputParameters coerces filterByCuration NULL -> FALSE but passes new boolean inputs and direction through without explicit defaulting. Consider explicit defaults (FALSE for booleans, "both" for direction) to avoid passing NULL to MSstatsBioNet::getSubnetworkFromIndra.
  3. Documentation missing:

    • extractSubnetwork lacks updated roxygen/docs for the new parameters; add descriptions for filter_by_ptm_site, include_infinite_fc, and direction.
  4. Redundant useShinyjs():

    • useShinyjs() is called both at module-level and inside createAdvancedOptionsCollapsible(); one call at module root is sufficient.
  5. Expanded import surface:

    • NAMESPACE now imports shiny::actionLink and shinyjs::toggle. Confirm intentionality and update package documentation if needed.
  6. Downstream compatibility:

    • Ensure other callers, examples, or integration tests are updated for the extended extractSubnetwork signature to avoid runtime/mocking mismatches.

@coderabbitai
Copy link

coderabbitai bot commented Mar 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2cab5292-9574-418a-95bc-2a1533dfc1d5

📥 Commits

Reviewing files that changed from the base of the PR and between 4122b7c and 1ad4f74.

📒 Files selected for processing (2)
  • R/module-visualize-network-server.R
  • tests/testthat/test_network_visualization.R
🚧 Files skipped from review as they are similar to previous changes (2)
  • R/module-visualize-network-server.R
  • tests/testthat/test_network_visualization.R

📝 Walkthrough

Walkthrough

Adds two imports to NAMESPACE (shiny::actionLink, shinyjs::toggle), introduces a collapsible "Advanced Options" UI with three new filters (filter_by_ptm_site, include_infinite_fc, direction), threads those inputs through input collection and visualizeNetworkServer, extends extractSubnetwork signature, updates generated network code, and adjusts tests.

Changes

Cohort / File(s) Summary
Package Imports
NAMESPACE, R/MSstatsShiny.R
Added importFrom(shiny, actionLink) and importFrom(shinyjs, toggle) to support advanced UI toggling.
Advanced Options UI
R/module-visualize-network-ui.R
Replaced static curation checkbox with a collapsible "Advanced Options" panel (uses useShinyjs() and an actionLink); added filter_by_ptm_site, include_infinite_fc, and direction inputs, tooltips, and createAdvancedOptionsCollapsible(ns); updated data upload composition to use it.
Server parameter threading & codegen
R/module-visualize-network-server.R
Extended getInputParameters to read new inputs, wired input$toggle_adv for panel visibility, propagated filter_by_ptm_site, include_infinite_fc, and direction through visualizeNetworkServer → extractSubnetwork → getSubnetworkFromIndra, and updated generated network code to emit the new args.
Core function & tests
R/.../extractSubnetwork*, tests/testthat/test_network_visualization.R
Extended extractSubnetwork(...) signature to accept filter_by_ptm_site, include_infinite_fc, and direction; updated tests to mock and assert forwarding of these parameters and adjusted calls to include them.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant UI as Advanced Options Panel
    participant Server as visualizeNetworkServer
    participant Input as getInputParameters
    participant Extract as extractSubnetwork
    participant INDRA as getSubnetworkFromIndra

    User->>UI: Click actionLink (toggle)
    UI->>UI: (shinyjs::toggle) show/hide advanced options
    User->>UI: Set filter_by_ptm_site / include_infinite_fc / direction
    Server->>Input: getInputParameters() reads inputs
    Input-->>Server: return parameters (including new filters)
    Server->>Extract: extractSubnetwork(..., filter_by_ptm_site, include_infinite_fc, direction)
    Extract->>INDRA: getSubnetworkFromIndra(..., filter_by_ptm_site, include_infinite_fc, direction)
    INDRA-->>Extract: filtered subnetwork
    Extract-->>Server: network result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 A toggle clicked, a panel springs,

Filters hop in on feathered wings.
PTM, infinite, direction too,
Through server paths they bound and skew.
Subnetworks dance — the rabbit cheers!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding an advanced options panel for subnetwork search filtering, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature-advanced-options

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Namespacing Bug

The advanced options toggle calls shinyjs::toggle(id = "adv_panel") from within a module, but the UI element id is namespaced via ns("adv_panel"). This will likely prevent the panel from toggling unless the server uses the namespaced id (e.g., session$ns("adv_panel")).

observeEvent(input$toggle_adv, {
  toggle(id = "adv_panel", anim = TRUE)
})
Code Generation

The generated code appends direction = using the raw value from params$direction, which is a character string (both/up/down). Without quoting/escaping, the produced R code will be invalid (it will emit direction = both instead of direction = "both").

codes <- paste(codes, ",\n  filter_by_curation = ", params$filterByCuration, "\n", sep = "")
codes <- paste(codes, ",\n  filter_by_ptm_site = ", params$filter_by_ptm_site, "\n", sep = "")
codes <- paste(codes, ",\n  include_infinite_fc = ", params$include_infinite_fc, "\n", sep = "")
codes <- paste(codes, ",\n  direction = ", params$direction, "\n", sep = "")
Input Defaults

New parameters are passed through (filter_by_ptm_site, include_infinite_fc, direction) without req()/defaults/coercion. If any of these are temporarily NULL during initialization/reactivity, or if getSubnetworkFromIndra() doesn’t accept NULL, subnetwork extraction may fail; consider explicit defaults/coercion (e.g., isTRUE() for checkboxes).

  proteinIdType = req(input$proteinIdType),
  pValue = as.numeric(req(input$pValue)),
  evidence = as.numeric(req(input$evidence)),
  absLogFC = as.numeric(req(input$absLogFC)),
  statementTypes = statementTypes,
  sources = sources,
  selectedLabel = req(input$selectedLabel),
  selectedProteins = selectedProteins,
  filterByCuration = filterByCuration,
  filter_by_ptm_site = input$filter_by_ptm_site,
  include_infinite_fc = input$include_infinite_fc,
  direction = input$direction
)

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Toggle the namespaced panel id

In a Shiny module, DOM ids are namespaced, so toggling "adv_panel" directly may not
find the element. Toggle the namespaced id (e.g., via NS(id, ...) or
session$ns(...)) so the advanced panel reliably opens/closes.

R/module-visualize-network-server.R [395-397]

 observeEvent(input$toggle_adv, {
-  toggle(id = "adv_panel", anim = TRUE)
+  toggle(id = NS(id, "adv_panel"), anim = TRUE)
 })
Suggestion importance[1-10]: 8

__

Why: In a Shiny module, the UI element id is created via ns("adv_panel"), so calling toggle(id = "adv_panel") likely won’t match the DOM node and the advanced panel won’t open/close. Using a namespaced id (e.g., NS(id, "adv_panel") or session$ns("adv_panel")) fixes the module behavior.

Medium
Quote string values in generated code

params$direction is a character value, but the generated R code omits quotes,
producing invalid code like direction = both. Quote the value when pasting so the
output is executable.

R/module-visualize-network-server.R [565]

-codes <- paste(codes, ",\n  direction = ", params$direction, "\n", sep = "")
+codes <- paste0(codes, ",\n  direction = ", shQuote(params$direction), "\n")
Suggestion importance[1-10]: 6

__

Why: params$direction is a character (e.g., both/up/down), and emitting it without quotes makes the generated R code invalid (direction = both). Using shQuote(params$direction) produces executable code without changing runtime logic.

Low
Enforce stable input types

These inputs can be NULL before initialization or if the UI conditionally hides
them, which can break downstream filtering. Coerce checkboxes to strict logicals and
require direction to be present before use.

R/module-visualize-network-server.R [184-187]

 filterByCuration = filterByCuration,
-filter_by_ptm_site = input$filter_by_ptm_site,
-include_infinite_fc = input$include_infinite_fc,
-direction = input$direction
+filter_by_ptm_site = isTRUE(input$filter_by_ptm_site),
+include_infinite_fc = isTRUE(input$include_infinite_fc),
+direction = req(input$direction)
Suggestion importance[1-10]: 4

__

Why: Coercing checkbox inputs with isTRUE() can make downstream code more robust if these values ever come through as NULL. However, these inputs are always present in the UI (just hidden), so the practical impact is limited and req(input$direction) is likely unnecessary given the default selection.

Low

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
R/module-visualize-network-server.R (1)

214-229: ⚠️ Potential issue | 🔴 Critical

The MSstatsBioNet API does not document support for the three new parameters.

According to the official MSstatsBioNet package documentation, getSubnetworkFromIndra() does not include filter_by_ptm_site, include_infinite_fc, or direction parameters. Passing these undocumented arguments will cause a runtime error ("unused argument") unless your project depends on an unreleased or modified version of MSstatsBioNet. Confirm that the MSstatsBioNet version constraint in your DESCRIPTION file or package dependencies explicitly requires a version that supports these parameters, or remove them from the function call.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/module-visualize-network-server.R` around lines 214 - 229, The call to
getSubnetworkFromIndra inside extractSubnetwork passes three parameters that
MSstatsBioNet does not document (filter_by_ptm_site, include_infinite_fc,
direction); remove these three arguments from the getSubnetworkFromIndra(...)
invocation in extractSubnetwork or alternatively update the package
dependency/version in DESCRIPTION to a specific MSstatsBioNet release that
explicitly supports those parameters—search for the extractSubnetwork function
and the getSubnetworkFromIndra call to apply the change and keep the remaining
named arguments unchanged.
🧹 Nitpick comments (1)
R/module-visualize-network-ui.R (1)

260-260: Remove redundant useShinyjs() call.

useShinyjs() is already called in the main networkUI function at line 468. Calling it again inside createAdvancedOptionsCollapsible is redundant and can cause initialization issues or warnings. It should only be included once in the UI hierarchy.

♻️ Proposed fix
 createAdvancedOptionsCollapsible <- function(ns) {
   div(
     style = "margin-bottom: 15px;", 
     tagList(
-      useShinyjs(),
       actionLink(
         ns("toggle_adv"),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/module-visualize-network-ui.R` at line 260, Remove the redundant
useShinyjs() call inside createAdvancedOptionsCollapsible: locate the function
createAdvancedOptionsCollapsible and delete the useShinyjs() invocation so that
useShinyjs() is only called once in the top-level networkUI function; ensure no
other duplicate initializations remain in helper UI functions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@R/module-visualize-network-server.R`:
- Around line 563-565: The generated code writes params$direction without quotes
causing R to treat it as a symbol; update the string concatenation that builds
codes (the line referencing params$direction) to wrap the value in quotes (e.g.,
emit "direction = \"<value>\"" or use shQuote(params$direction)) so the produced
R code contains a quoted string ("both"/"up"/"down"); keep the other
concatenations unchanged.
- Around line 395-397: The toggle call inside observeEvent(input$toggle_adv)
uses the un-namespaced id "adv_panel" and must use the module namespace: change
the toggle invocation in the observeEvent (where input$toggle_adv is handled) to
call toggle(id = session$ns("adv_panel"), anim = TRUE) so it targets the
ns("adv_panel") element created in the UI within this module.
- Around line 214-216: Update the test calls to match the new extractSubnetwork
signature: in the tests that call extractSubnetwork (from
tests/testthat/test_network_visualization.R around the earlier failing calls),
pass the three new arguments filter_by_ptm_site, include_infinite_fc, and
direction (e.g., FALSE, FALSE, "both") as the 9th–11th parameters so the call
becomes extractSubnetwork(annotated_df, pValue, evidence, statementTypes,
sources, absLogFC, selectedProteins, filterByCuration, FALSE, FALSE, "both");
ensure all test invocations of extractSubnetwork use these three additional
arguments.

---

Outside diff comments:
In `@R/module-visualize-network-server.R`:
- Around line 214-229: The call to getSubnetworkFromIndra inside
extractSubnetwork passes three parameters that MSstatsBioNet does not document
(filter_by_ptm_site, include_infinite_fc, direction); remove these three
arguments from the getSubnetworkFromIndra(...) invocation in extractSubnetwork
or alternatively update the package dependency/version in DESCRIPTION to a
specific MSstatsBioNet release that explicitly supports those parameters—search
for the extractSubnetwork function and the getSubnetworkFromIndra call to apply
the change and keep the remaining named arguments unchanged.

---

Nitpick comments:
In `@R/module-visualize-network-ui.R`:
- Line 260: Remove the redundant useShinyjs() call inside
createAdvancedOptionsCollapsible: locate the function
createAdvancedOptionsCollapsible and delete the useShinyjs() invocation so that
useShinyjs() is only called once in the top-level networkUI function; ensure no
other duplicate initializations remain in helper UI functions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 813e9dc4-43e2-4e66-8f6f-bbd9d2b1157c

📥 Commits

Reviewing files that changed from the base of the PR and between 520b3e4 and a514f14.

📒 Files selected for processing (4)
  • NAMESPACE
  • R/MSstatsShiny.R
  • R/module-visualize-network-server.R
  • R/module-visualize-network-ui.R

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
R/module-visualize-network-server.R (1)

184-187: Consider adding defensive NULL handling for new parameters.

The existing filterByCuration parameter has explicit NULL handling (Lines 169-173), but the new parameters are read directly from input without defaults. If the UI inputs haven't been initialized or are conditionally hidden, these could be NULL.

♻️ Suggested defensive handling
     filterByCuration = filterByCuration,
-    filter_by_ptm_site = input$filter_by_ptm_site,
-    include_infinite_fc = input$include_infinite_fc,
-    direction = input$direction
+    filter_by_ptm_site = if (is.null(input$filter_by_ptm_site)) FALSE else input$filter_by_ptm_site,
+    include_infinite_fc = if (is.null(input$include_infinite_fc)) FALSE else input$include_infinite_fc,
+    direction = if (is.null(input$direction)) "both" else input$direction
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@R/module-visualize-network-server.R` around lines 184 - 187, The new
parameters (filter_by_ptm_site, include_infinite_fc, direction) should get the
same defensive NULL handling as filterByCuration: when building the list passed
into the module, replace direct input reads with guarded expressions (e.g., for
filter_by_ptm_site and include_infinite_fc coerce NULL to FALSE, and for
direction coerce NULL to a sensible default such as "both" or the module's
expected default) so the code using filterByCuration, filter_by_ptm_site,
include_infinite_fc, and direction never receives NULL; implement these guards
using if (is.null(input$...)) <default> else input$... or a coalescing helper
before passing them through.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/testthat/test_network_visualization.R`:
- Around line 182-186: The error test still calls extractSubnetwork with the old
8-argument signature (see the failing call using create_mock_annotated_data()) —
update that test to call extractSubnetwork with the new 11 parameters (add the
three new params: filterByCuration, filter_by_ptm_site, include_infinite_fc) in
the same order used elsewhere (e.g., direction = "both"); ensure the error
handling invocation matches the updated signature of extractSubnetwork so the
test exercises the intended error path.

---

Nitpick comments:
In `@R/module-visualize-network-server.R`:
- Around line 184-187: The new parameters (filter_by_ptm_site,
include_infinite_fc, direction) should get the same defensive NULL handling as
filterByCuration: when building the list passed into the module, replace direct
input reads with guarded expressions (e.g., for filter_by_ptm_site and
include_infinite_fc coerce NULL to FALSE, and for direction coerce NULL to a
sensible default such as "both" or the module's expected default) so the code
using filterByCuration, filter_by_ptm_site, include_infinite_fc, and direction
never receives NULL; implement these guards using if (is.null(input$...))
<default> else input$... or a coalescing helper before passing them through.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 42d9ab12-1543-4dd5-b461-a430dee35889

📥 Commits

Reviewing files that changed from the base of the PR and between a514f14 and 4122b7c.

📒 Files selected for processing (2)
  • R/module-visualize-network-server.R
  • tests/testthat/test_network_visualization.R

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant