stitch-ui
Version:
159 lines (144 loc) • 4.73 kB
JavaScript
/* eslint-disable react/no-array-index-key */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import React from "react";
import PropTypes from "prop-types";
import { JSONState, PipelineStageEditState } from "../../models";
import { Dropdown } from "../../core";
import DefaultStageEditor from "../../services/components/DefaultStageEditor";
import { findServiceDefinition } from "../../services/registry";
import { toJSON } from "../../util";
// TODO use withMutations throughout, bc it's faster.
export default class PipelineStageEditor extends React.Component {
constructor(props) {
super(props);
this.state = { servicesDropdownOpen: false, actionsDropdownOpen: false };
this.onDoneEditing = this.onDoneEditing.bind(this);
this.initEditState = this.initEditState.bind(this);
this.changeService = this.changeService.bind(this);
this.changeAction = this.changeAction.bind(this);
}
componentDidMount() {
this.initEditState();
}
onDoneEditing(stage) {
this.props.setStage(stage);
this.props.onClose();
return Promise.resolve();
}
initEditState() {
const action = findServiceDefinition(
this.props.editState.get("service"),
this.props.services
).actions.get(this.props.editState.get("action"));
if (action) {
this.props.applyEditChange(s =>
s.set("initArgsInput", toJSON(action.defaultArgs))
);
}
}
changeAction(k) {
if (k === this.props.editState.get("action")) {
return;
}
const action = findServiceDefinition(
this.props.editState.get("service"),
this.props.services
).actions.get(k);
if (action) {
const newArgs = action.defaultArgs.toJS();
this.applyChange(this.props.editState.get("service"), k, newArgs);
return;
}
this.props.applyEditChange(s => s.set("action", k));
}
changeService(k) {
if (k === this.props.editState.get("service")) {
return;
}
const defaultAction = findServiceDefinition(k, this.props.services).actions
.toList()
.get(0);
if (defaultAction) {
const newArgs = defaultAction.defaultArgs.toJS();
this.applyChange(k, defaultAction.name, newArgs);
return;
}
this.props.applyEditChange(s => s.set("service", k).set("action", ""));
}
applyChange(service, action, args) {
const currentInput = this.props.editState.getIn(["argsInput", "input"]);
const initInput = this.props.editState.get("initArgsInput");
this.props.applyEditChange(s =>
s
.set("service", service)
.set("action", action)
.set("initArgsInput", toJSON(args))
);
if (currentInput && currentInput === initInput) {
this.props.applyEditChange(s =>
s.set("argsInput", JSONState.fromRaw(args))
);
}
}
render() {
const { services, editState, applyEditChange, onClose } = this.props;
const selectedServiceName = editState.get("service") || "built-in";
return (
<div>
<Dropdown text={selectedServiceName} label="Service">
<li onClick={() => this.changeService("")}>
<span>built-in</span>
</li>
{Object.entries(services).map(([k]) =>
<li key={k} onClick={() => this.changeService(k)}>
<span>
{k}
</span>
</li>
)}
</Dropdown>
<Dropdown text={editState.get("action")} label="action">
{findServiceDefinition(
editState.get("service") || "",
services
).actions
.map((svc, svcName) =>
<li key={svcName} onClick={() => this.changeAction(svcName)}>
<span>
{svcName}
</span>
</li>
)
.toArray()}
</Dropdown>
<div>
<DefaultStageEditor
ref={editor => (this.editor = editor)}
onDoneEditing={this.onDoneEditing}
editState={editState}
applyEditChange={applyEditChange}
onCancel={onClose}
/>
</div>
</div>
);
}
}
const servicePropTypes = PropTypes.shape({
type: PropTypes.string.isRequired,
config: PropTypes.object,
rules: PropTypes.object.isRequired
});
/* eslint-disable react/forbid-prop-types */
PipelineStageEditor.propTypes = {
services: PropTypes.objectOf(servicePropTypes).isRequired,
editState: PropTypes.instanceOf(PipelineStageEditState),
setStage: PropTypes.func.isRequired,
applyEditChange: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired
};
PipelineStageEditor.defaultProps = {
open: false,
editState: null
};