Skip to content

feature(network visualization): Redirect users to INDRA when clicking an edge#115

Merged
tonywu1999 merged 3 commits intodevelfrom
bionet
Sep 5, 2025
Merged

feature(network visualization): Redirect users to INDRA when clicking an edge#115
tonywu1999 merged 3 commits intodevelfrom
bionet

Conversation

@tonywu1999
Copy link
Copy Markdown
Contributor

@tonywu1999 tonywu1999 commented Sep 5, 2025

PR Type

Enhancement, Bug fix


Description

  • Add edge evidence link propagation

  • Open evidence links in new tab

  • Handle empty/invalid URLs safely

  • Integrate edge click with table highlight


Diagram Walkthrough

flowchart LR
  A["Cytoscape edge click (JS)"] -- "send edge data incl. evidenceLink" --> B["Shiny input edgeClicked"]
  B -- "server observes" --> C["highlightEdgeInTable"]
  B -- "extract evidenceLink" --> D["openEvidenceLink(session, url)"]
  D -- "custom message" --> E["UI handler openLinkInNewTab"]
  E -- "window.open(url, _blank)" --> F["New browser tab"]
Loading

File Walkthrough

Relevant files
Enhancement
module-visualize-network-server.R
Add evidence link handling and opening logic                         

R/module-visualize-network-server.R

  • Include evidenceLink in edge click payload.
  • Add openEvidenceLink helper with validation.
  • Trigger link opening on edge click after highlighting.
+14/-1   
module-visualize-network-ui.R
UI handler to open links in new tab                                           

R/module-visualize-network-ui.R

  • Add custom message handler openLinkInNewTab.
  • Safely open non-empty URLs in a new tab with error logging.
+13/-0   

Summary by CodeRabbit

  • New Features
    • Clicking a network edge now opens its associated evidence link in a new browser tab for quick access to source material.
    • Edge interactions now include an “evidence link” attribute, enabling direct navigation from the visualization.
    • After an edge is highlighted in the edges table, the related evidence page automatically opens to streamline review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 5, 2025

Walkthrough

Adds propagation of an evidenceLink field from Cytoscape edge clicks, a server helper openEvidenceLink(session, evidence_link) that emits a custom Shiny message openLinkInNewTab, and a client-side message handler that validates and opens the URL in a new browser tab.

Changes

Cohort / File(s) Summary of Changes
Server: edge click handling & message emitter
R/module-visualize-network-server.R
Edge click payload handling extended to include evidenceLink; new function openEvidenceLink(session, evidence_link) added to validate URL and send a custom Shiny message openLinkInNewTab; edgeClicked path now calls this helper after updating selection.
UI: client message handler for opening links
R/module-visualize-network-ui.R
Adds a Shiny.addCustomMessageHandler openLinkInNewTab in the Cytoscape scripts output: trims/validates message.url, enforces http/https, opens link via window.open(url, '_blank', 'noopener,noreferrer'), and catches/logs errors.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Cyt as Cytoscape (client)
  participant Server as Shiny Server (module)
  participant Browser as Browser

  User->>Cyt: click edge
  Cyt-->>Server: edge_click event { source, target, ..., evidenceLink }
  Server->>Server: extract & validate evidenceLink
  Server-->>Cyt: shiny.sendCustomMessage("openLinkInNewTab", { url })
  note right of Server: new message type emitted
  Cyt->>Browser: window.open(url, "_blank", "noopener,noreferrer")
  note right of Browser: evidence opens in new tab
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I hop along the graph so spry,
An edge goes click — a link jumps high!
A tiny message sails the way,
A new tab opens — off I stray.
Evidence found, I nibble and sigh. 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e7e7d12 and bcd37d4.

📒 Files selected for processing (2)
  • R/module-visualize-network-server.R (3 hunks)
  • R/module-visualize-network-ui.R (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • R/module-visualize-network-ui.R
  • R/module-visualize-network-server.R
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bionet

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 5, 2025

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 Security concerns

Open redirect / unvalidated URL:
Evidence links from edge data are opened in a new tab with minimal validation on both server and client. If edge data can be influenced by untrusted sources, this could facilitate phishing or unwanted navigation. Consider validating URLs (scheme whitelist like https/http), optionally enforcing allowed hostnames (e.g., indra.*), and using rel="noopener noreferrer" semantics (window.open already creates a new context, but adding 'noopener' via feature string is safer: window.open(url, '_blank', 'noopener');).

⚡ Recommended focus areas for review

URL Validation

The client-side handler only checks for non-empty strings before window.open; consider validating URL format or restricting to expected domains to avoid opening malformed or unsafe URLs.

Shiny.addCustomMessageHandler('openLinkInNewTab', function(message) {
  try {
    if (message.url) {
      if (message.url.trim() !== '') {
        window.open(message.url, '_blank');
      }
    }
  } catch (err) {
    console.error('Error opening link:', err);
  }
});
Null Safety

Server-side openEvidenceLink checks for NULL/empty/NA but does not trim whitespace; trailing spaces may bypass the check and still open an invalid tab.

openEvidenceLink <- function(session, evidence_link) {
  if (!is.null(evidence_link) && evidence_link != "" && !is.na(evidence_link)) {
    # Send JavaScript command to open link in new tab
    session$sendCustomMessage(
      type = 'openLinkInNewTab',
      message = list(url = evidence_link)
    )
  }
}

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 5, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Security
Validate and sanitize URL

Guard against non-character inputs to avoid warnings/errors from is.na on non-atomic
types and accidental object injection. Coerce to character and validate it is a
single, http(s) URL before sending to the client.

R/module-visualize-network-server.R [137-145]

 openEvidenceLink <- function(session, evidence_link) {
-  if (!is.null(evidence_link) && evidence_link != "" && !is.na(evidence_link)) {
-    # Send JavaScript command to open link in new tab
-    session$sendCustomMessage(
-      type = 'openLinkInNewTab',
-      message = list(url = evidence_link)
-    )
-  }
+  if (is.null(evidence_link)) return(invisible(NULL))
+  # Coerce to character and keep first element
+  url <- as.character(evidence_link)[1]
+  if (!nzchar(url)) return(invisible(NULL))
+  # Basic allow-list check for http(s)
+  if (!grepl("^https?://", url, ignore.case = TRUE)) return(invisible(NULL))
+  session$sendCustomMessage(
+    type = "openLinkInNewTab",
+    message = list(url = url)
+  )
+  invisible(NULL)
 }
Suggestion importance[1-10]: 8

__

Why: Adds robust input validation and scheme allow-listing for openEvidenceLink, reducing XSS/open-redirect risk and handling non-character inputs; directly applicable to the new function.

Medium
Enforce safe URL scheme

Prevent potential injection or non-URL values by validating the URL schema before
opening. Only allow http(s) links and reject others to avoid executing unintended
protocols.

R/module-visualize-network-ui.R [21-31]

 Shiny.addCustomMessageHandler('openLinkInNewTab', function(message) {
   try {
-    if (message.url) {
-      if (message.url.trim() !== '') {
-        window.open(message.url, '_blank');
-      }
-    }
+    const url = (message && typeof message.url === 'string') ? message.url.trim() : '';
+    if (!url) return;
+    // Allow only http(s) schemes
+    if (!/^https?:\/\//i.test(url)) return;
+    window.open(url, '_blank', 'noopener,noreferrer');
   } catch (err) {
     console.error('Error opening link:', err);
   }
 });
Suggestion importance[1-10]: 8

__

Why: Strengthens client-side safety by restricting to http(s) and using noopener,noreferrer, preventing abuse of other schemes and improving security; matches the added handler.

Medium
Possible issue
Safely access optional field

Ensure edge_data$evidenceLink exists to avoid reactive errors when the field is
missing on some edges. Use a safe extractor with fallback to NULL.

R/module-visualize-network-server.R [501-510]

 observeEvent(input$edgeClicked, {
   edge_data <- input$edgeClicked
   network_data <- renderNetwork()
   req(network_data)
   edges_table <- network_data$edges_table
   
   highlightEdgeInTable(output, edge_data, edges_table)
-  openEvidenceLink(session, edge_data$evidenceLink)
+  evidence_link <- tryCatch(edge_data$evidenceLink, error = function(e) NULL)
+  openEvidenceLink(session, evidence_link)
 })
Suggestion importance[1-10]: 6

__

Why: Using a safe extractor avoids errors if evidenceLink is absent; moderate impact since the server helper already validates, but still improves robustness at the call site.

Low

Copy link
Copy Markdown

@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: 2

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

32-34: Include defensive default and trim on evidenceLink before sending to server.

If edge.data('evidenceLink') is undefined, Shiny may omit the field entirely. Consider normalizing to null client-side to make server logic simpler, but current approach is acceptable.


509-509: Potential popup blockers; consider client-side open within the Cytoscape click handler.

Many browsers block window.open unless triggered synchronously by a user gesture. As an enhancement, also call window.open from the JS edge click handler (in addition to server flow) when evidenceLink is present.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fdef91a and e7e7d12.

📒 Files selected for processing (2)
  • R/module-visualize-network-server.R (3 hunks)
  • R/module-visualize-network-ui.R (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Comment thread R/module-visualize-network-server.R
Comment thread R/module-visualize-network-ui.R
@tonywu1999 tonywu1999 merged commit f515632 into devel Sep 5, 2025
2 checks passed
@tonywu1999 tonywu1999 deleted the bionet branch September 5, 2025 19:38
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