diff options
author | Zuul <zuul@review.opendev.org> | 2019-08-08 21:23:22 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2019-08-08 21:23:22 +0000 |
commit | 459ee2f1d3c18ef264b473d75850ffdec6fd163e (patch) | |
tree | 4657dcd2b630e4a557fb7fbfdc6014f968b9a8d4 | |
parent | 9bde4211a706c6ca618aba3e7cda91b0dce08efe (diff) | |
parent | 5b0bbb6ca5fc76af90421d05f81a925147af3021 (diff) | |
download | zuul-459ee2f1d3c18ef264b473d75850ffdec6fd163e.tar.gz |
Merge "Add permalinks to task detail popup"
-rw-r--r-- | web/src/containers/build/Console.jsx | 51 | ||||
-rw-r--r-- | web/src/index.css | 5 | ||||
-rw-r--r-- | web/src/pages/BuildConsole.jsx | 4 |
3 files changed, 51 insertions, 9 deletions
diff --git a/web/src/containers/build/Console.jsx b/web/src/containers/build/Console.jsx index e5067bd1e..9843aeb17 100644 --- a/web/src/containers/build/Console.jsx +++ b/web/src/containers/build/Console.jsx @@ -60,6 +60,20 @@ function hasInterestingKeys (obj, keys) { return ret } +function makeTaskPath (path) { + return path.join('/') +} + +function taskPathMatches (ref, test) { + if (test.length < ref.length) + return false + for (let i=0; i < ref.length; i++) { + if (ref[i] !== test[i]) + return false + } + return true +} + class TaskOutput extends React.Component { static propTypes = { data: PropTypes.object, @@ -180,6 +194,8 @@ class HostTask extends React.Component { task: PropTypes.object, host: PropTypes.object, errorIds: PropTypes.object, + taskPath: PropTypes.array, + displayPath: PropTypes.array, } state = { @@ -201,13 +217,16 @@ class HostTask extends React.Component { constructor (props) { super(props) - const { host } = this.props + const { host, taskPath, displayPath } = this.props hostTaskStats(this.state, host) + + if (taskPathMatches(taskPath, displayPath)) + this.state.showModal = true } render () { - const { hostname, task, host, errorIds } = this.props + const { hostname, task, host, taskPath, errorIds } = this.props const ai = [] if (this.state.skipped) { @@ -244,6 +263,7 @@ class HostTask extends React.Component { ) const expand = errorIds.has(task.task.id) + let name = task.task.name if (!name) { name = host.action @@ -286,7 +306,13 @@ class HostTask extends React.Component { > <Icon type="pf" name="close" /> </button> - <Modal.Title>{hostname}</Modal.Title> + <Modal.Title>{hostname} + <span className="zuul-console-modal-header-link"> + <a href={'#'+makeTaskPath(taskPath)}> + <Icon type="fa" name="link" title="Permalink" /> + </a> + </span> + </Modal.Title> </Modal.Header> <Modal.Body> <TaskOutput data={host}/> @@ -301,13 +327,17 @@ class PlayBook extends React.Component { static propTypes = { playbook: PropTypes.object, errorIds: PropTypes.object, + taskPath: PropTypes.array, + displayPath: PropTypes.array, } render () { - const { playbook, errorIds } = this.props + const { playbook, errorIds, taskPath, displayPath } = this.props const expandAll = (playbook.phase === 'run') - const expand = (expandAll || errorIds.has(playbook.phase + playbook.index)) + const expand = (expandAll || + errorIds.has(playbook.phase + playbook.index) || + taskPathMatches(taskPath, displayPath)) const ai = [] if (playbook.trusted) { @@ -340,7 +370,10 @@ class PlayBook extends React.Component { <Row key={idx2+hostname}> <Col sm={12}> <HostTask hostname={hostname} - task={task} host={host} errorIds={errorIds}/> + taskPath={taskPath.concat([ + idx.toString(), idx2.toString(), hostname])} + displayPath={displayPath} task={task} host={host} + errorIds={errorIds}/> </Col> </Row> ))))} @@ -354,6 +387,7 @@ class PlayBook extends React.Component { class Console extends React.Component { static propTypes = { output: PropTypes.array, + displayPath: PropTypes.array, } constructor (props) { @@ -394,13 +428,14 @@ class Console extends React.Component { } render () { - const { output } = this.props + const { output, displayPath } = this.props return ( <React.Fragment> <ListView key="playbooks" className="zuul-console"> {output.map((playbook, idx) => ( - <PlayBook key={idx} playbook={playbook} errorIds={this.errorIds}/>))} + <PlayBook key={idx} playbook={playbook} taskPath={[idx.toString()]} + displayPath={displayPath} errorIds={this.errorIds}/>))} </ListView> </React.Fragment> ) diff --git a/web/src/index.css b/web/src/index.css index 5f917e77e..9e7ac0138 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -226,6 +226,11 @@ pre.version { { cursor: default; } +.zuul-console-modal-header-link +{ + margin-left: 2em; + font-size: 18px; +} .zuul-console-task-detail { width: 80%; diff --git a/web/src/pages/BuildConsole.jsx b/web/src/pages/BuildConsole.jsx index 7ffba3d26..550197e41 100644 --- a/web/src/pages/BuildConsole.jsx +++ b/web/src/pages/BuildConsole.jsx @@ -42,6 +42,8 @@ class BuildConsolePage extends Refreshable { render () { const { remoteData } = this.props const build = remoteData.builds[this.props.match.params.buildId] + const hash = this.props.location.hash.substring(1).split('/') + return ( <React.Fragment> <div style={{float: 'right'}}> @@ -49,7 +51,7 @@ class BuildConsolePage extends Refreshable { </div> {build && build.output && <Build build={build} active='console'> - <Console output={build.output}/> + <Console output={build.output} displayPath={hash.length>0?hash:undefined}/> </Build>} </React.Fragment> ) |