[master] WIP tracking bug that refreshes RunDetails when it should not. Half way finished with unFollow.
This commit is contained in:
parent
f78c07e3bd
commit
cb3eef2400
|
@ -1,4 +1,5 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Extensions from '@jenkins-cd/js-extensions';
|
||||
import LogConsole from './LogConsole';
|
||||
import * as sse from '@jenkins-cd/sse-gateway';
|
||||
|
@ -21,6 +22,20 @@ import LogToolbar from './LogToolbar';
|
|||
const { string, object, any, func } = PropTypes;
|
||||
|
||||
export class RunDetailsPipeline extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
// we do not want to follow any builds that are finished
|
||||
this.state = { followAlong: props && props.result && props.result.state !== 'FINISHED' ? true : false };
|
||||
}
|
||||
|
||||
// shouldComponentUpdate(nextProps) {
|
||||
// if(nextProps.result.id ===this.props.result.id) {
|
||||
// console.log('up', nextProps)
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
componentWillMount() {
|
||||
const { fetchNodes, fetchLog, result, fetchSteps } = this.props;
|
||||
const mergedConfig = this.generateConfig(this.props);
|
||||
|
@ -36,37 +51,83 @@ export class RunDetailsPipeline extends Component {
|
|||
|
||||
// Listen for pipeline flow node events.
|
||||
// We filter them only for steps and the end event all other we let pass
|
||||
this.pipelineListener = sse.subscribe('pipeline', (event) => {
|
||||
const onSseEvent = (event) => {
|
||||
const jenkinsEvent = event.jenkins_event;
|
||||
// we turn on refetch so we always fetch a new Node result
|
||||
const refetch = true;
|
||||
switch (jenkinsEvent) {
|
||||
case 'pipeline_step': {
|
||||
// if the step_stage_id has changed we need to change the focus
|
||||
if (event.pipeline_step_stage_id !== mergedConfig.node) {
|
||||
mergedConfig.node = event.pipeline_step_stage_id;
|
||||
fetchNodes({ ...mergedConfig, refetch });
|
||||
} else {
|
||||
fetchSteps({ ...mergedConfig, refetch });
|
||||
try {
|
||||
if (!this.state.followAlong || event.pipeline_run_id !== this.props.result.id) {
|
||||
console.log('early out');
|
||||
throw new Error('exit');
|
||||
}
|
||||
// we turn on refetch so we always fetch a new Node result
|
||||
const refetch = true;
|
||||
switch (jenkinsEvent) {
|
||||
case 'pipeline_step':
|
||||
{
|
||||
// if the step_stage_id has changed we need to change the focus
|
||||
if (event.pipeline_step_stage_id !== mergedConfig.node) {
|
||||
fetchNodes({ ...mergedConfig, refetch });
|
||||
} else {
|
||||
fetchSteps({ ...mergedConfig, refetch });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'pipeline_end':
|
||||
{
|
||||
fetchNodes({ ...mergedConfig, refetch });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// console.log(event);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// we only ignore the exit error
|
||||
if (e.message !== 'exit') {
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'pipeline_end': {
|
||||
fetchNodes({ ...mergedConfig, refetch });
|
||||
break;
|
||||
};
|
||||
|
||||
console.log('?', this.state.followAlong)
|
||||
if (this.state.followAlong) {
|
||||
this.pipelineListener = sse.subscribe('pipeline', onSseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
const onScrollHandler = (elem) => {
|
||||
if (elem.deltaY < 0 && this.state.followAlong) {
|
||||
console.log('this.setState({ followAlong: false });');
|
||||
this.setState({ followAlong: false });
|
||||
}
|
||||
default: {
|
||||
// console.log(event);
|
||||
};
|
||||
|
||||
const _handleKeys = (event) => {
|
||||
if (event.keyCode === 38 && this.state.followAlong) {
|
||||
console.log('this.setState({ followAlong: false });');
|
||||
this.setState({ followAlong: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
const domNode = ReactDOM.findDOMNode(this.refs.scrollArea);
|
||||
domNode.addEventListener('wheel', onScrollHandler, false);
|
||||
document.addEventListener('keydown', _handleKeys, false);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (!this.state.followAlong && this.timeout) {
|
||||
console.log('clearTO');
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
if (nextProps.params.node !== this.props.params.node) {
|
||||
const config = this.generateConfig(nextProps);
|
||||
this.props.setNode(config);
|
||||
this.props.fetchSteps(config);
|
||||
if (!this.state.followAlong) {
|
||||
this.setState({ followAlong: true });
|
||||
}
|
||||
}
|
||||
|
||||
const { logs, fetchLog } = nextProps;
|
||||
|
@ -78,8 +139,12 @@ export class RunDetailsPipeline extends Component {
|
|||
const newStart = log.newStart;
|
||||
if (Number(newStart) > 0) {
|
||||
// kill current timeout if any
|
||||
console.log('prefollow', this.state.followAlong);
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => fetchLog({ ...logGeneral, newStart }), 1000);
|
||||
if (this.state.followAlong) {
|
||||
console.log('follow', this.state.followAlong);
|
||||
this.timeout = setTimeout(() => fetchLog({ ...logGeneral, newStart }), 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,11 +192,15 @@ export class RunDetailsPipeline extends Component {
|
|||
} = this.props;
|
||||
|
||||
const {
|
||||
result,
|
||||
state,
|
||||
result,
|
||||
state,
|
||||
} = resultMeta;
|
||||
const resultRun = result === 'UNKNOWN' || !result ? state : result;
|
||||
const scrollToBottom = resultRun.toLowerCase() === 'failure' || resultRun.toLowerCase() === 'running';
|
||||
const followAlong = this.state.followAlong;
|
||||
const scrollToBottom =
|
||||
resultRun.toLowerCase() === 'failure'
|
||||
|| (resultRun.toLowerCase() === 'running' && followAlong)
|
||||
;
|
||||
|
||||
const mergedConfig = this.generateConfig(this.props);
|
||||
|
||||
|
@ -145,8 +214,13 @@ export class RunDetailsPipeline extends Component {
|
|||
} else if (mergedConfig.nodeReducer.id !== null) {
|
||||
title = `Steps - ${title}`;
|
||||
}
|
||||
console.log(followAlong, 'followAlongsteps');
|
||||
const stopFollowing = (event) => {
|
||||
console.log(this.refs, event, !followAlong);
|
||||
this.setState({ followAlong: !followAlong });
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div ref="scrollArea">
|
||||
{ nodes && nodes[nodeKey] && <Extensions.Renderer
|
||||
extensionPoint="jenkins.pipeline.run.result"
|
||||
router={router}
|
||||
|
@ -157,6 +231,7 @@ export class RunDetailsPipeline extends Component {
|
|||
runId={runId}
|
||||
/>
|
||||
}
|
||||
<button onClick={stopFollowing}>noFollow</button>
|
||||
<LogToolbar
|
||||
fileName={logGeneral.fileName}
|
||||
url={logGeneral.url}
|
||||
|
@ -164,6 +239,7 @@ export class RunDetailsPipeline extends Component {
|
|||
/>
|
||||
{ steps && steps[key] && <Steps
|
||||
nodeInformation={steps[key]}
|
||||
followAlong
|
||||
{...this.props}
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ export default class Node extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { node, logs, nodesBaseUrl, fetchLog } = this.props;
|
||||
const { node, logs, nodesBaseUrl, fetchLog, followAlong } = this.props;
|
||||
// Early out
|
||||
if (!node || !fetchLog) {
|
||||
return null;
|
||||
|
@ -64,7 +64,7 @@ export default class Node extends Component {
|
|||
};
|
||||
const runResult = resultRun.toLowerCase();
|
||||
const scrollToBottom = runResult === 'failure' || runResult === 'running';
|
||||
|
||||
console.log(followAlong, 'followAlong_step')
|
||||
return (<div>
|
||||
<ResultItem
|
||||
key={id}
|
||||
|
|
|
@ -706,6 +706,7 @@ export const actions = {
|
|||
so we only fetch them once.
|
||||
*/
|
||||
fetchSteps(config) {
|
||||
console.log('rfetch');
|
||||
return (dispatch, getState) => {
|
||||
const data = getState().adminStore.steps;
|
||||
const stepBaseUrl = calculateStepsBaseUrl(config);
|
||||
|
|
|
@ -47,7 +47,7 @@ export const uriString = (input) => encodeURIComponent(input).replace(/%2F/g, '%
|
|||
export const calculateLogUrl = (config) => {
|
||||
if (config.node) {
|
||||
const { nodesBaseUrl, node } = config;
|
||||
return `${nodesBaseUrl}/${node.id}/log`;
|
||||
return `${nodesBaseUrl}/${node.id}/log/`;
|
||||
}
|
||||
return config.url;
|
||||
};
|
||||
|
@ -83,11 +83,10 @@ export function calculateStepsBaseUrl(config) {
|
|||
baseUrl = `${baseUrl}/branches/${branch}`;
|
||||
}
|
||||
if (node && node !== null) {
|
||||
return `${baseUrl}/runs/${runId}/nodes/${node}/steps`;
|
||||
return `${baseUrl}/runs/${runId}/nodes/${node}/steps/`;
|
||||
}
|
||||
return `${baseUrl}/runs/${runId}/steps/`;
|
||||
}
|
||||
|
||||
/*
|
||||
* helper to calculate general log url, includes filename.
|
||||
* If we have multibranch we generate a slightly different url
|
||||
|
|
|
@ -98,7 +98,7 @@ describe('UrlUtils', () => {
|
|||
}
|
||||
);
|
||||
|
||||
assert.equal(url, `${testUrl}/1/log`);
|
||||
assert.equal(url, `${testUrl}/1/log/`);
|
||||
});
|
||||
});
|
||||
describe('calculate calculateNodeBaseUrl', () => {
|
||||
|
@ -133,7 +133,7 @@ describe('UrlUtils', () => {
|
|||
const node = 15;
|
||||
const url = calculateStepsBaseUrl({...testData, node});
|
||||
assert.equal(url, `${testData._appURLBase}/rest/organizations/jenkins/` +
|
||||
`pipelines/${testData.name}/runs/${testData.runId}/nodes/${node}/steps`);
|
||||
`pipelines/${testData.name}/runs/${testData.runId}/nodes/${node}/steps/`);
|
||||
});
|
||||
it('should build the url with mutibranch and no node', () => {
|
||||
const isMultiBranch = true;
|
||||
|
|
Loading…
Reference in New Issue