insomnia/app/ui/components/templating/variable-editor.js
Gregory Schier 253cdfeb57 A few tweaks to nunjucks modal (#126)
* A few tweaks to nunjucks modal

* <select> for tag editor and minor tweaks

* Pass unique key to nunjucks modal

* Slightly better autocomplete

* Warn user when switching body type

* Ability to do custom templating in nunjucks editors

* Make constants matcher more strict
2017-03-31 14:59:12 -07:00

113 lines
2.9 KiB
JavaScript

import React, {PropTypes, PureComponent} from 'react';
import autobind from 'autobind-decorator';
@autobind
class VariableEditor extends PureComponent {
constructor (props) {
super(props);
const inner = props.defaultValue
.replace(/\s*}}$/, '')
.replace(/^{{\s*/, '');
this.state = {
variables: [],
value: `{{ ${inner} }}`,
preview: '',
error: ''
};
}
componentDidMount () {
this._update(this.state.value, true);
}
_handleChange (e) {
this._update(e.target.value);
}
_setSelectRef (n) {
this._select = n;
// Let it render, then focus the input
setTimeout(() => {
this._select && this._select.focus();
}, 100);
}
async _update (value, noCallback = false) {
const {handleRender} = this.props;
let preview = '';
let error = '';
try {
preview = await handleRender(value, true);
} catch (err) {
error = err.message;
}
const context = await this.props.handleGetRenderContext();
const variables = context.keys;
// Hack to skip updating if we unmounted for some reason
if (this._select) {
this.setState({preview, error, variables, value});
}
// Call the callback if we need to
if (!noCallback) {
this.props.onChange(value);
}
}
render () {
const {error, value, preview, variables} = this.state;
const isOther = !variables.find(v => value === `{{ ${v.name} }}`);
return (
<div>
<div className="form-control form-control--outlined">
<label>Environment Variable
<select ref={this._setSelectRef}
value={value}
defaultValue={null}
onChange={this._handleChange}>
<option value={`{{ 'my custom template logic' | urlencode }}`}>
-- Custom Template --
</option>
{variables.map((v, i) => (
<option key={`${i}::${v.name}`} value={`{{ ${v.name} }}`}>
{v.name}
</option>
))}
</select>
</label>
</div>
{isOther ? (
<div className="form-control form-control--outlined">
<input type="text" defaultValue={value} onChange={this._handleChange}/>
</div>
) : null}
<div className="form-control form-control--outlined">
<label>Live Preview
{error
? <code className="block danger selectable">{error || <span>&nbsp;</span>}</code>
: <code className="block selectable">{preview || <span>&nbsp;</span>}</code>
}
</label>
</div>
</div>
);
}
}
VariableEditor.propTypes = {
handleRender: PropTypes.func.isRequired,
handleGetRenderContext: PropTypes.func.isRequired,
defaultValue: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired
};
export default VariableEditor;