UNPKG

stitch-ui

Version:

276 lines (267 loc) 9.91 kB
// 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> ); } }