Skip to content

Commit 35d875d

Browse files
committed
Pipeline validation added to edit component.
1 parent 99c6a66 commit 35d875d

File tree

5 files changed

+452
-16
lines changed

5 files changed

+452
-16
lines changed

src/components/Pipelines/VariableForm/VariableForm.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Button, { TheButtonGroup } from '../../widgets/TheButton';
1111
import Callout from '../../widgets/Callout';
1212
import SubmitButton from '../../forms/SubmitButton';
1313
import { CloseIcon, SaveIcon, RefreshIcon } from '../../../components/icons';
14-
import { isArrayType } from '../../../helpers/pipelines';
14+
import { KNOWN_DATA_TYPES, isArrayType } from '../../../helpers/pipelines';
1515

1616
export const newVariableInitialData = {
1717
name: '',
@@ -21,10 +21,7 @@ export const newVariableInitialData = {
2121
external: false,
2222
};
2323

24-
const variableTypeOptions = ['file', 'remote-file', 'string']
25-
.reduce((acc, type) => [...acc, type, type + '[]'], [])
26-
.sort()
27-
.map(type => ({ key: type, name: type }));
24+
const variableTypeOptions = KNOWN_DATA_TYPES.map(type => ({ key: type, name: type }));
2825

2926
class VariableForm extends Component {
3027
render() {

src/containers/PipelineEditContainer/PipelineEditContainer.js

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ import VariablesTable from '../../components/Pipelines/VariablesTable';
1111
import VariableForm, { newVariableInitialData } from '../../components/Pipelines/VariableForm';
1212
import BoxForm, { newBoxInitialData } from '../../components/Pipelines/BoxForm';
1313
import Button, { TheButtonGroup } from '../../components/widgets/TheButton';
14+
import Callout from '../../components/widgets/Callout';
1415
import Icon, { RefreshIcon, SaveIcon, UndoIcon, RedoIcon } from '../../components/icons';
1516

16-
import { fetchSupplementaryFilesForPipeline } from '../../redux/modules/pipelineFiles';
17-
1817
import {
1918
getVariablesUtilization,
2019
isArrayType,
@@ -23,12 +22,18 @@ import {
2322
getReferenceIdentifier,
2423
makeExternalReference,
2524
getVariablesTypes,
25+
validatePipeline,
2626
} from '../../helpers/pipelines';
2727
import { getBoxTypes } from '../../redux/selectors/boxes';
2828
import { objectMap, arrayToObject, encodeId, deepCompare, identity } from '../../helpers/common';
2929

3030
import styles from '../../components/Pipelines/styles.less';
3131

32+
const getFormattedErrorAsKey = element => {
33+
const values = element.props.values ? { ...element.props.values } : {};
34+
delete values.code;
35+
return `${element.props.id}-${Object.values(values).join('_')}`;
36+
};
3237
// TODO
3338

3439
/*
@@ -90,24 +95,41 @@ class PipelineEditContainer extends Component {
9095
version: null,
9196
boxes: null,
9297
variables: null,
98+
boxTypes: null,
99+
errors: [],
93100
history: [],
94101
future: [],
95102
...STATE_DEFAULTS,
96103
};
97104

98105
static getDerivedStateFromProps(nextProps, prevState) {
99106
if (prevState.pipelineId !== nextProps.pipeline.id) {
107+
// pipeline was changed whilst component was kept mounted => complete reload
100108
return {
101109
pipelineId: nextProps.pipeline.id,
102110
version: nextProps.pipeline.version,
103111
boxes: nextProps.pipeline.pipeline.boxes,
104112
variables: nextProps.pipeline.pipeline.variables,
113+
boxTypes: nextProps.boxTypes,
114+
errors: validatePipeline(
115+
nextProps.pipeline.pipeline.boxes,
116+
nextProps.pipeline.pipeline.variables,
117+
nextProps.boxTypes
118+
),
105119
history: [],
106120
future: [],
107121
...STATE_DEFAULTS,
108122
};
109123
}
110124

125+
if (prevState.boxTypes !== nextProps.boxTypes) {
126+
// boxTypes changed (probably get loaded) -> revalidate
127+
return {
128+
boxTypes: nextProps.boxTypes,
129+
errors: validatePipeline(prevState.boxes, prevState.variables, nextProps.boxTypes),
130+
};
131+
}
132+
111133
if (prevState.version < nextProps.pipeline.version) {
112134
// TODO -- deal with mergin issues
113135
return { version: nextProps.pipeline.version };
@@ -126,6 +148,11 @@ class PipelineEditContainer extends Component {
126148

127149
this.setState({
128150
...restore,
151+
errors: validatePipeline(
152+
restore.boxes || this.state.boxes,
153+
restore.variables || this.state.variables,
154+
this.props.boxTypes
155+
),
129156
history,
130157
future: [snapshot, ...this.state.future],
131158
selectedBoxVariables: _getSelectedBoxVariables(this.state.selectedBox, restore.boxes || this.state.boxes),
@@ -143,6 +170,11 @@ class PipelineEditContainer extends Component {
143170

144171
this.setState({
145172
...restore,
173+
errors: validatePipeline(
174+
restore.boxes || this.state.boxes,
175+
restore.variables || this.state.variables,
176+
this.props.boxTypes
177+
),
146178
history: [snapshot, ...this.state.history],
147179
future,
148180
selectedBoxVariables: _getSelectedBoxVariables(this.state.selectedBox, restore.boxes || this.state.boxes),
@@ -163,6 +195,11 @@ class PipelineEditContainer extends Component {
163195
version: this.props.pipeline.version,
164196
boxes: this.props.pipeline.pipeline.boxes,
165197
variables: this.props.pipeline.pipeline.variables,
198+
errors: validatePipeline(
199+
this.props.pipeline.pipeline.boxes,
200+
this.props.pipeline.pipeline.variables,
201+
this.props.boxTypes
202+
),
166203
history: [],
167204
future,
168205
...STATE_DEFAULTS,
@@ -284,6 +321,11 @@ class PipelineEditContainer extends Component {
284321
if (pipelineChanged) {
285322
stateUpdate.history = [snapshot, ...this.state.history];
286323
stateUpdate.future = [];
324+
stateUpdate.errors = validatePipeline(
325+
stateUpdate.boxes || this.state.boxes,
326+
stateUpdate.variables || this.state.variables,
327+
this.props.boxTypes
328+
);
287329
}
288330

289331
// update (recompute) selections if necessary
@@ -461,6 +503,7 @@ class PipelineEditContainer extends Component {
461503
<Box
462504
title={<FormattedMessage id="app.pipelineEditContainer.title" defaultMessage="Edit Pipeline Structure" />}
463505
unlimitedHeight
506+
type={this.state.errors && this.state.errors.length > 0 ? 'danger' : 'light'}
464507
footer={
465508
<div className="text-center" style={{ marginBottom: '-0.75rem' }}>
466509
<TheButtonGroup className={styles.mainButtonGroup}>
@@ -490,7 +533,7 @@ class PipelineEditContainer extends Component {
490533
</TheButtonGroup>
491534

492535
<TheButtonGroup className={styles.mainButtonGroup}>
493-
<Button variant="success">
536+
<Button variant="success" disabled={this.state.errors && this.state.errors.length > 0}>
494537
<SaveIcon gapRight />
495538
<FormattedMessage id="generic.save" defaultMessage="Save" />
496539
</Button>
@@ -537,6 +580,27 @@ class PipelineEditContainer extends Component {
537580
)}
538581
</Col>
539582
</Row>
583+
584+
{this.state.errors && this.state.errors.length > 0 && (
585+
<Row>
586+
<Col xl={12}>
587+
<Callout variant="danger">
588+
<h5>
589+
<FormattedMessage
590+
id="app.pipelineEditContainer.errorsCalloutTitle"
591+
defaultMessage="The following errors were found in the pipeline"
592+
/>
593+
:
594+
</h5>
595+
<ul>
596+
{this.state.errors.map(error => (
597+
<li key={getFormattedErrorAsKey(error)}>{error}</li>
598+
))}
599+
</ul>
600+
</Callout>
601+
</Col>
602+
</Row>
603+
)}
540604
</Container>
541605

542606
<BoxForm
@@ -579,12 +643,12 @@ PipelineEditContainer.propTypes = {
579643
};
580644

581645
export default connect(
582-
(state, { pipeline }) => {
646+
state => {
583647
return {
584648
boxTypes: getBoxTypes(state),
585649
};
586650
},
587651
(dispatch, { pipeline }) => ({
588-
loadFiles: () => dispatch(fetchSupplementaryFilesForPipeline(pipeline.id)),
652+
//
589653
})
590654
)(PipelineEditContainer);

0 commit comments

Comments
 (0)