summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames E. Blair <jim@acmegating.com>2022-07-29 11:39:23 -0700
committerJames E. Blair <jim@acmegating.com>2022-08-02 08:03:32 -0700
commitdb445d5cac4a9851c509fa54bb8786451b9ed59e (patch)
treec169c2bf3947d65c769096b6ec6ee1889bf09b55
parent2111c7cf96e11b5b2d96f3abda5526022639a4fe (diff)
downloadzuul-db445d5cac4a9851c509fa54bb8786451b9ed59e.tar.gz
Use internal links in job graph display
Since we're using the graphviz library to render an svg, we can't just pass in a react router Link object for the node links we create for jobs. But we can manipulate the DOM after the SVG is produced and add onClick handlers that do the same thing. This avoids refreshing the page/app when clicking on links in the graph. Change-Id: Ie173e3d2e31efd47dbe4a44fda8b743250729339
-rw-r--r--web/src/containers/jobgraph/JobGraphDisplay.jsx20
1 files changed, 15 insertions, 5 deletions
diff --git a/web/src/containers/jobgraph/JobGraphDisplay.jsx b/web/src/containers/jobgraph/JobGraphDisplay.jsx
index 8d55c8f54..9bd67e7d2 100644
--- a/web/src/containers/jobgraph/JobGraphDisplay.jsx
+++ b/web/src/containers/jobgraph/JobGraphDisplay.jsx
@@ -16,12 +16,11 @@ import React, { useState, useEffect} from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import * as d3 from 'd3'
+import { useHistory } from 'react-router-dom'
import { makeJobGraphKey, fetchJobGraphIfNeeded } from '../../actions/jobgraph'
import { graphviz } from 'd3-graphviz'
-import { getHomepageUrl } from '../../api'
-
function makeDot(tenant, pipeline, project, branch, jobGraph) {
let ret = 'digraph job_graph {\n'
ret += ' rankdir=LR;\n'
@@ -32,8 +31,11 @@ function makeDot(tenant, pipeline, project, branch, jobGraph) {
searchParams.append('project', project.name)
searchParams.append('job', job.name)
searchParams.append('branch', branch)
- const url = (getHomepageUrl() + tenant.linkPrefix +
- 'freeze-job?' + searchParams.toString())
+ // This will appear in the DOM as an "a href=" but we will
+ // manipulate the DOM later to add an onClick callback to make
+ // this an internal link.
+ const url = (tenant.linkPrefix +
+ '/freeze-job?' + searchParams.toString())
// Escape ampersands to get it through graphviz and d3; these will
// appear unescaped in the DOM.
const escaped_url = url.replace(/&/g, '&amp;')
@@ -53,6 +55,8 @@ function makeDot(tenant, pipeline, project, branch, jobGraph) {
}
function GraphViz(props) {
+ const history = useHistory()
+
useEffect(() => {
const gv = graphviz('#graphviz')
.options({
@@ -72,7 +76,13 @@ function GraphViz(props) {
gv._translation.y = val
gv._originalTransform.y = val
}
- }, [props.dot])
+
+ // Mutate the links to be internal links
+ d3.select('.zuul-job-graph').selectAll('.node a').on('click', event => {
+ d3.event.preventDefault()
+ history.push(event.attributes['xlink:href'])
+ })
+ }, [props.dot, history])
return (
<div className="zuul-job-graph" id="graphviz"/>