diff options
author | James E. Blair <jim@acmegating.com> | 2022-07-29 11:39:23 -0700 |
---|---|---|
committer | James E. Blair <jim@acmegating.com> | 2022-08-02 08:03:32 -0700 |
commit | db445d5cac4a9851c509fa54bb8786451b9ed59e (patch) | |
tree | c169c2bf3947d65c769096b6ec6ee1889bf09b55 /web/src/containers | |
parent | 2111c7cf96e11b5b2d96f3abda5526022639a4fe (diff) | |
download | zuul-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
Diffstat (limited to 'web/src/containers')
-rw-r--r-- | web/src/containers/jobgraph/JobGraphDisplay.jsx | 20 |
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, '&') @@ -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"/> |