stitch-ui
Version:
276 lines (267 loc) • 9.91 kB
JavaScript
// TODO proptypes
/* eslint-disable react/prop-types */
// TODO get rid of refs.
/* eslint-disable react/no-string-refs */
/* eslint-disable react/no-array-index-key */
import React from "react";
import PipelineEditor from "../../pipelineeditor/components/PipelineEditor";
import PipelineParameter from "./PipelineParameter";
import { NamedPipeline } from "../../models";
import { AlertContainer } from "../../alert";
import {
Banner,
Tooltip,
RichJSONEditor,
Spinner,
FormRow,
FormRowLabelGroup,
FormRowInputGroup,
Button,
SplitPanel,
Panel
} from "../../core";
export default class NamedPipelineEditor extends React.Component {
constructor(props) {
super(props);
this.save = this.save.bind(this);
}
save(pipeline) {
let name;
if (this.refs.name) {
name = this.refs.name.value;
} else {
name = this.props.editing.name;
}
if (!name || name.length === 0) {
this.props.setSavePipelineError({ name: "Name must not be blank" });
return Promise.resolve();
}
const canEvalParsed = this.props.editing.canEvaluate.parseInput();
this.props.setCanEval(canEvalParsed);
if (canEvalParsed.error) {
return Promise.resolve();
}
return this.props.savePipeline(
new NamedPipeline({
output: pipeline.output,
name,
canEvaluate: canEvalParsed,
parameters: this.props.editing.parameters,
private: this.props.editing.private,
skipRules: this.props.editing.skipRules,
pipeline
})
);
}
render() {
const {
error,
editing,
remove,
services,
discardChanges,
addParameter,
removeParameter,
editingPipeline,
updateParameter,
updateCanEvalInput,
setSkipRules,
setPrivate
} = this.props;
return (
<SplitPanel right>
<Panel dirty={editing.dirty || editingPipeline.dirty}>
<div className="panel-header">
{editing && editing.name
? <div>
<h3 className="panel-header-title">
{editing.name}
</h3>
</div>
: <div className="panel-header-title">
<label className="panel-header-title-label" htmlFor="name">
New Pipeline Name
</label>
<Banner message={(error || {}).name} error />
<input
name="name"
ref="name"
type="text"
className="text-input form-row-text-input panel-header-title-input"
placeholder="Pipeline Name"
/>
</div>}
<div className="slide-toggle-round-container">
<h5 className="slide-toggle-round-label">
Private
<Tooltip
dataFor="private-tooltip"
place="top"
classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary"
effect="float"
>
If selected, this pipeline may be called only from incoming
webhooks, rules, and other pipelines defined in the Stitch
Admin console.<br />Private pipelines may not be called from
Stitch client applications.
</Tooltip>
</h5>
<div className="switch">
<input
id="private"
type="checkbox"
name="private"
onChange={e => setPrivate(e.target.checked)}
checked={editing.private}
className="slide-toggle-round"
/>
<label htmlFor="private" />
</div>
</div>
<div className="slide-toggle-round-container">
<h5 className="slide-toggle-round-label">
Skip Rules
<Tooltip
dataFor="skip-rules-tooltip"
place="top"
classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary"
effect="float"
>
If selected, this pipeline’s service actions bypass any rules
and filters defined for those services.<br />However, you must
provide an expression in the <code>Can Evaluate</code> box
when this capability is enabled.
</Tooltip>
</h5>
<div className="switch">
<input
id="skipRules"
type="checkbox"
name="skipRules"
onChange={e => setSkipRules(e.target.checked)}
checked={editing.skipRules}
className="slide-toggle-round"
/>
<label htmlFor="skipRules" />
</div>
</div>
<div className="panel-header-actions">
<AlertContainer alertKey="namedpipeline" />
<Spinner open={this.props.savingPipeline} />
<Button
small
primary
disabled={this.props.savingPipeline}
ref={pipelineEditor => (this.pipelineEditor = pipelineEditor)}
onClick={() =>
this.pipelineEditor.getWrappedInstance().child.submit()}
>
Save
</Button>
{editing && editing.name
? <Button
small
onClick={remove}
disabled={this.props.savingPipeline}
>
Delete
</Button>
: <Button small onClick={remove}>
{" "}Cancel{" "}
</Button>}
</div>
</div>
<div className="panel-content">
<Banner message={(error || {}).submit} error />
<FormRow>
<FormRowLabelGroup>
<Banner message={editing.canEvaluate.error} error />
<label className="form-row-label" htmlFor="canEvaluate">
Can Evaluate
<Tooltip
dataFor="can-evaluate-tooltip"
place="top"
classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary"
effect="float"
>
An expression in the format of a JSON document that must
evaluate to <code>true</code> before the pipeline may run.<br />The
expression can include expansions.<br />An empty JSON
document always evaluates to <code>true</code>, indicating
that the pipeline can always be run.<br />This
pipeline-specific expression is evaluated before other
service-specific rules.<br />An expression is required when
Skip Rules is enabled for the named pipeline.
</Tooltip>
</label>
</FormRowLabelGroup>
<FormRowInputGroup>
<Banner message={(error || {}).canEvaluate} error />
<RichJSONEditor
minLines={10}
maxLines={10}
width={"100%"}
id={"canEvaluate"}
value={editing.canEvaluate.input}
onChange={e => updateCanEvalInput(e)}
/>
</FormRowInputGroup>
</FormRow>
<FormRow>
<FormRowLabelGroup>
<label className="form-row-label" htmlFor="params">
Parameters
<Tooltip
dataFor="parameters-tooltip"
place="top"
classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary"
effect="float"
>
Specify parameters that can be accessed by any stage in the
named pipeline with the <code>$$args</code> expansion.<br />Toggle
the REQUIRED switch to specify that a parameter is required
to execute the pipeline.
</Tooltip>
</label>
</FormRowLabelGroup>
<FormRowInputGroup>
{(editing.parameters || [])
.map((p, i) =>
<PipelineParameter
key={i}
index={i}
parameter={p}
removeParameter={removeParameter}
updateParameter={pr => updateParameter(i, pr)}
/>
)}
<Button small onClick={addParameter}>
+ Add Parameter
</Button>
</FormRowInputGroup>
</FormRow>
<PipelineEditor
ref={pipelineEditor => (this.pipelineEditor = pipelineEditor)}
pipelineKey="namedpipeline"
alertKey="_"
onSubmit={this.save}
saveButtonText="Save"
services={services}
/>
</div>
{(editing.dirty || editingPipeline.dirty) &&
<div className="panel-discard">
<div className="panel-discard-modified">
You have unsaved changes.
</div>
<div className="panel-discard-controls">
<Button small default onClick={discardChanges}>
Discard Changes
</Button>
</div>
</div>}
</Panel>
</SplitPanel>
);
}
}