[ux-412] Working version after merge
This commit is contained in:
parent
15c67cc1fb
commit
fceb1763a8
|
@ -2,7 +2,7 @@ root = true
|
|||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
|
@ -1,5 +1,11 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import { actions, pipelines as pipelinesSelector, connect, createSelector } from './redux';
|
||||
import {
|
||||
actions,
|
||||
pipelines as pipelinesSelector,
|
||||
isMultiBranch as isMultiBranchSelector,
|
||||
connect,
|
||||
createSelector,
|
||||
} from './redux';
|
||||
import * as sse from '@jenkins-cd/sse-gateway';
|
||||
import * as pushEventUtil from './util/push-event-util';
|
||||
|
||||
|
@ -12,6 +18,7 @@ sse.connect('jenkins_blueocean');
|
|||
|
||||
class OrganisationPipelines extends Component {
|
||||
|
||||
// FIXME: IMO the following should be droped
|
||||
getChildContext() {
|
||||
const {
|
||||
params,
|
||||
|
@ -36,8 +43,14 @@ class OrganisationPipelines extends Component {
|
|||
}
|
||||
|
||||
componentWillMount() {
|
||||
if (this.context.config) {
|
||||
this.props.fetchPipelinesIfNeeded(this.context.config);
|
||||
const config = this.context.config;
|
||||
if (config) {
|
||||
this.props.fetchPipelinesIfNeeded(config);
|
||||
if (this.props.params.pipeline) {
|
||||
const { pipeline } = this.props.params;
|
||||
config.pipeline = pipeline;
|
||||
this.props.setPipeline(config);
|
||||
}
|
||||
const _this = this;
|
||||
|
||||
// Subscribe for job channel push events
|
||||
|
@ -71,15 +84,29 @@ class OrganisationPipelines extends Component {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.params.pipeline !== this.props.params.pipeline) {
|
||||
const config = this.context.config;
|
||||
const { pipeline } = nextProps.params;
|
||||
config.pipeline = pipeline;
|
||||
this.props.setPipeline(config);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.jobListener) {
|
||||
sse.unsubscribe(this.jobListener);
|
||||
delete this.jobListener;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FIXME we should use clone here, this way we could pass all actions and reducer down to all
|
||||
components and get rid of the seperate connect in each subcomponents -> see RunDetailsPipeline
|
||||
*/
|
||||
render() {
|
||||
return this.props.children; // Set by router
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +117,7 @@ OrganisationPipelines.contextTypes = {
|
|||
|
||||
OrganisationPipelines.propTypes = {
|
||||
fetchPipelinesIfNeeded: func.isRequired,
|
||||
setPipeline: func,
|
||||
processJobQueuedEvent: func.isRequired,
|
||||
updateRunState: func.isRequired,
|
||||
params: object, // From react-router
|
||||
|
@ -105,6 +133,7 @@ OrganisationPipelines.childContextTypes = {
|
|||
location: object, // From react-router
|
||||
};
|
||||
|
||||
const selectors = createSelector([pipelinesSelector], (pipelines) => ({ pipelines }));
|
||||
const selectors = createSelector([pipelinesSelector, isMultiBranchSelector],
|
||||
(pipelines, isMultiBranch) => ({ pipelines, isMultiBranch }));
|
||||
|
||||
export default connect(selectors, actions)(OrganisationPipelines);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import { Icon } from 'react-material-icons-blue';
|
||||
import { StatusIndicator } from '@jenkins-cd/design-language';
|
||||
import moment from 'moment';
|
||||
import { calculateLogUrl } from '../redux';
|
||||
|
||||
|
@ -7,22 +8,6 @@ import LogConsole from './LogConsole';
|
|||
|
||||
const { object, func, string } = PropTypes;
|
||||
|
||||
function iconFromResult(result) {
|
||||
switch (result) {
|
||||
case 'SUCCESS':
|
||||
case 'UNSTABLE':
|
||||
return 'done';
|
||||
case 'FAILURE':
|
||||
case 'ABORTED':
|
||||
case 'NOT_BUILT':
|
||||
return 'close';
|
||||
case 'RUNNING':
|
||||
return 'track_changes';
|
||||
default:
|
||||
return 'close';
|
||||
}
|
||||
}
|
||||
|
||||
export default class Node extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -40,22 +25,22 @@ export default class Node extends Component {
|
|||
render() {
|
||||
const { node, logs, nodesBaseUrl, fetchLog } = this.props;
|
||||
const { isVisible } = this.state;
|
||||
// Early out
|
||||
// Early out
|
||||
if (!node || !fetchLog) {
|
||||
return null;
|
||||
}
|
||||
const { config = {} } = this.context;
|
||||
const {
|
||||
key,
|
||||
title,
|
||||
durationInMillis,
|
||||
result,
|
||||
state,
|
||||
} = node;
|
||||
key,
|
||||
title,
|
||||
durationInMillis,
|
||||
result,
|
||||
state,
|
||||
} = node;
|
||||
|
||||
const newVar = result === 'UNKNOWN' || !result ? state : result;
|
||||
const resultRun = result === 'UNKNOWN' || !result ? state : result;
|
||||
const duration = moment.duration(
|
||||
Number(durationInMillis), 'milliseconds').humanize();
|
||||
Number(durationInMillis), 'milliseconds').humanize();
|
||||
const log = logs ? logs[calculateLogUrl({ ...config, node, nodesBaseUrl })] : null;
|
||||
|
||||
const getLogForNode = () => {
|
||||
|
@ -68,7 +53,12 @@ export default class Node extends Component {
|
|||
return (<div>
|
||||
<div className="nodes" key={key} onClick={getLogForNode}>
|
||||
<div className="nodes__section">
|
||||
<div className="result"><Icon {...{ icon: iconFromResult(newVar) }} /></div>
|
||||
<div className="result"><StatusIndicator result={resultRun} /></div>
|
||||
<div className="state">
|
||||
{ this.state.isVisible ?
|
||||
<Icon {...{ icon: 'keyboard_arrow_down' }} /> :
|
||||
<Icon {...{ icon: 'keyboard_arrow_right' }} />}
|
||||
</div>
|
||||
<div className="title">{title}</div>
|
||||
</div>
|
||||
<div className="nodes__section">
|
|
@ -19,6 +19,7 @@ export default class Nodes extends Component {
|
|||
key={index}
|
||||
node={item}
|
||||
nodesBaseUrl={nodesBaseUrl}
|
||||
{...this.props}
|
||||
/>)
|
||||
}
|
||||
</div>);
|
|
@ -40,14 +40,13 @@ class RunDetails extends Component {
|
|||
componentWillMount() {
|
||||
if (this.context.config && this.context.params) {
|
||||
const {
|
||||
params: {
|
||||
pipeline,
|
||||
},
|
||||
config = {},
|
||||
} = this.context;
|
||||
params: {
|
||||
pipeline,
|
||||
},
|
||||
config = {},
|
||||
} = this.context;
|
||||
config.pipeline = pipeline;
|
||||
this.props.fetchRunsIfNeeded(config);
|
||||
this.props.setPipeline(config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,36 +26,38 @@ export class RunDetailsPipeline extends Component {
|
|||
|
||||
generateConfig() {
|
||||
const {
|
||||
params: {
|
||||
pipeline: name, branch, runId,
|
||||
},
|
||||
config = {},
|
||||
} = this.context;
|
||||
params: { pipeline: name, branch, runId },
|
||||
config = {},
|
||||
} = this.context;
|
||||
const { isMultiBranch } = this.props;
|
||||
const mergedConfig = { ...config, name, branch, runId, isMultiBranch };
|
||||
return mergedConfig;
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { pipeline: name, branch, runId } = this.context.params;
|
||||
const { isMultiBranch, nodes } = this.props;
|
||||
|
||||
if (!nodes) {
|
||||
return null;
|
||||
}
|
||||
const mergedConfig = this.generateConfig();
|
||||
const key = calculateNodeBaseUrl(mergedConfig);
|
||||
const logGeneral = calculateRunLogURLObject(mergedConfig);
|
||||
return (
|
||||
<div>
|
||||
<ExtensionPoint name="jenkins.pipeline.run.result"
|
||||
pipelineName={name}
|
||||
branchName={isMultiBranch ? branch : undefined}
|
||||
runId={runId}
|
||||
/>
|
||||
<LogToolbar fileName={logGeneral.fileName} url={logGeneral.url} />
|
||||
{ nodes && <Nodes
|
||||
nodeInformation={nodes[key]}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<ExtensionPoint name="jenkins.pipeline.run.result"
|
||||
pipelineName={name}
|
||||
branchName={isMultiBranch ? branch : undefined}
|
||||
runId={runId}
|
||||
/>
|
||||
<LogToolbar fileName={logGeneral.fileName} url={logGeneral.url} />
|
||||
{ nodes && <Nodes
|
||||
nodeInformation={nodes[key]}
|
||||
{...this.props}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,8 @@ export const actionHandlers = {
|
|||
if (!pipelines) {
|
||||
return state.set('pipeline', null);
|
||||
}
|
||||
const pipeline = pipelines.filter(item => item.name === id);
|
||||
// [].slice(0) returns a clone, we do need it for uniqueness
|
||||
const pipeline = pipelines.slice(0).filter(item => item.name === id);
|
||||
return state.set('pipeline', pipeline[0] ? pipeline[0] : null);
|
||||
},
|
||||
[ACTION_TYPES.CLEAR_CURRENT_RUN_DATA](state) {
|
||||
|
@ -198,6 +199,7 @@ export const actions = {
|
|||
dispatch({ type: ACTION_TYPES.CLEAR_PIPELINE_DATA });
|
||||
const pipelines = getState().adminStore.pipelines;
|
||||
|
||||
|
||||
if (!pipelines) {
|
||||
return dispatch(actions.fetchPipelinesIfNeeded(config))
|
||||
.then(() => dispatch({ id: config.pipeline, type: ACTION_TYPES.SET_PIPELINE }));
|
||||
|
@ -536,7 +538,7 @@ export const actions = {
|
|||
},
|
||||
/*
|
||||
Get a specific log for a node, fetch it only if needed.
|
||||
key for cache: nodesBaseUrl + nodeId
|
||||
key for cache: logUrl = calculateLogUrl
|
||||
*/
|
||||
fetchLog(config) {
|
||||
return (dispatch, getState) => {
|
||||
|
|
|
@ -16,6 +16,7 @@ export const nodes = createSelector([adminStore], store => store.nodes);
|
|||
export const currentBranches = createSelector([adminStore], store => store.currentBranches);
|
||||
export const isMultiBranch = createSelector(
|
||||
[pipeline], (pipe) => {
|
||||
console.log('dammit');
|
||||
if (pipe && pipe.organization) {
|
||||
return !!pipe.branchNames;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue