Compose capabilites into lifecycle

This commit is contained in:
Ivan Meredith 2016-07-24 20:07:11 +12:00 committed by Ivan Meredith
parent 6de0d01565
commit 14286862d1
3 changed files with 77 additions and 79 deletions

View File

@ -11,7 +11,7 @@ import {
connect,
} from '../redux';
import { MULTIBRANCH_PIPELINE } from '../Capabilities';
import { classMetadataStore } from '@jenkins-cd/js-extensions';
import { capabilityStore } from './Capability';
const { object, array, func, string, bool } = PropTypes;
@ -49,14 +49,6 @@ RunNonMultiBranchPipeline.propTypes = {
};
export class Activity extends Component {
constructor(props) {
super(props);
this.state = {
capabilities: undefined,
};
}
componentWillMount() {
if (this.context.config && this.context.params) {
const {
@ -71,42 +63,15 @@ export class Activity extends Component {
}
}
componentDidMount() {
const { pipeline } = this.props;
const self = this;
classMetadataStore.getClassMetadata(pipeline._class, (classMeta) => {
self._setState({
capabilities: classMeta.classes,
});
});
}
componentWillUnmount() {
this.unmounted = true;
}
_setState(stateObj) {
// Block calls to setState for components that are
// not in a mounted state.
if (!this.unmounted) {
this.setState(stateObj);
}
}
render() {
const { capabilities } = this.state;
const { runs, pipeline } = this.props;
// early out
if (!runs) {
return null;
}
if (!capabilities) {
return null;
}
const isMultiBranchPipeline = capabilities.find(cap => cap === MULTIBRANCH_PIPELINE) !== undefined;
const { capabilities } = this.props;
const isMultiBranchPipeline = capabilities.has(MULTIBRANCH_PIPELINE);
// Only show the Run button for non multi-branch pipelines.
// Multi-branch pipelines have the Run/play button beside them on
@ -173,9 +138,10 @@ Activity.contextTypes = {
Activity.propTypes = {
runs: array,
pipeline: object,
capabilities: object,
fetchRunsIfNeeded: func,
};
const selectors = createSelector([runsSelector], (runs) => ({ runs }));
export default connect(selectors, actions)(Activity);
export default connect(selectors, actions)(capabilityStore(props => props.pipeline._class)(Activity));

View File

@ -0,0 +1,62 @@
import React, { Component } from 'react';
import { classMetadataStore } from '@jenkins-cd/js-extensions';
export const capabilityStore = pipelineClass => ComposedComponent => class extends Component {
constructor(props) {
super(props);
this.state = {
capabilities: {
has: () => false,
},
};
}
componentDidMount() {
const self = this;
classMetadataStore.getClassMetadata(pipelineClass(this.props), (classMeta) => {
self._setState({
capabilities: self._classesToObj(classMeta.classes),
});
});
}
componentWillUnmount() {
this.unmounted = true;
}
_classesToObj(classes) {
if (!classes) {
return {
has: () => false,
};
}
return {
classes,
has: capability => classes.find(_class => _class === capability) !== undefined,
};
}
_setState(stateObj) {
// Block calls to setState for components that are
// not in a mounted state.
if (!this.unmounted) {
this.setState(stateObj);
}
}
render() {
const { capabilities } = this.state;
// Early out. Doing it here means we don't have to do it in
// the composed componenet
if (!capabilities.classes) {
return null;
}
// This passes all props and state to ComposedComponent where
// they will all show as props.
return <ComposedComponent {...this.props} {...this.state} />;
}
};

View File

@ -1,48 +1,14 @@
import React, { Component, PropTypes } from 'react';
import { classMetadataStore } from '@jenkins-cd/js-extensions';
import { capabilityStore } from './Capability';
const { string } = PropTypes;
export default class IfCapability extends Component {
constructor(props) {
super(props);
this.state = {
capabilities: undefined,
};
}
componentDidMount() {
const self = this;
classMetadataStore.getClassMetadata(this.props._class, (classMeta) => {
self._setState({
capabilities: classMeta.classes,
});
});
}
componentWillUnmount() {
this.unmounted = true;
}
_setState(stateObj) {
// Block calls to setState for components that are
// not in a mounted state.
if (!this.unmounted) {
this.setState(stateObj);
}
}
const { string, object } = PropTypes;
class IfCapability extends Component {
render() {
const { capabilities } = this.state;
const { capabilities } = this.props;
const { capability } = this.props;
// Exit early, we havent fetched the caps yet.
if (!capabilities) {
return null;
}
if (capabilities.find(cap => cap === capability)) {
if (capabilities.has(capability)) {
return this.props.children;
}
@ -53,5 +19,9 @@ export default class IfCapability extends Component {
IfCapability.propTypes = {
_class: string,
capability: string,
capabilities: object,
children: React.PropTypes.node,
};
export default capabilityStore(props => props._class)(IfCapability);