diff --git a/packages/insomnia-app/app/models/request.js b/packages/insomnia-app/app/models/request.js index 63629cb7e2..d60970dc98 100644 --- a/packages/insomnia-app/app/models/request.js +++ b/packages/insomnia-app/app/models/request.js @@ -39,6 +39,7 @@ export type RequestAuthentication = Object; export type RequestHeader = { name: string, value: string, + description?: string, disabled?: boolean, }; @@ -53,6 +54,7 @@ export type RequestParameter = { export type RequestBodyParameter = { name: string, value: string, + description?: string, disabled?: boolean, multiline?: string, id?: string, diff --git a/packages/insomnia-app/app/ui/components/editors/body/form-editor.js b/packages/insomnia-app/app/ui/components/editors/body/form-editor.js index df66c74be6..7904889323 100644 --- a/packages/insomnia-app/app/ui/components/editors/body/form-editor.js +++ b/packages/insomnia-app/app/ui/components/editors/body/form-editor.js @@ -24,6 +24,7 @@ class FormEditor extends PureComponent { allowMultiline namePlaceholder="name" valuePlaceholder="value" + descriptionPlaceholder="description" handleRender={handleRender} handleGetRenderContext={handleGetRenderContext} nunjucksPowerUserMode={nunjucksPowerUserMode} diff --git a/packages/insomnia-app/app/ui/components/editors/body/url-encoded-editor.js b/packages/insomnia-app/app/ui/components/editors/body/url-encoded-editor.js index 06aae453ed..4f425a5dde 100644 --- a/packages/insomnia-app/app/ui/components/editors/body/url-encoded-editor.js +++ b/packages/insomnia-app/app/ui/components/editors/body/url-encoded-editor.js @@ -23,6 +23,7 @@ class UrlEncodedEditor extends PureComponent { allowMultiline namePlaceholder="name" valuePlaceholder="value" + descriptionPlaceholder="description" onChange={onChange} handleRender={handleRender} handleGetRenderContext={handleGetRenderContext} diff --git a/packages/insomnia-app/app/ui/components/editors/request-headers-editor.js b/packages/insomnia-app/app/ui/components/editors/request-headers-editor.js index 063aaeead1..049fc32d71 100644 --- a/packages/insomnia-app/app/ui/components/editors/request-headers-editor.js +++ b/packages/insomnia-app/app/ui/components/editors/request-headers-editor.js @@ -131,6 +131,7 @@ class RequestHeadersEditor extends React.PureComponent { sortable namePlaceholder="header" valuePlaceholder="value" + descriptionPlaceholder="description" pairs={request.headers} nunjucksPowerUserMode={nunjucksPowerUserMode} isVariableUncovered={isVariableUncovered} diff --git a/packages/insomnia-app/app/ui/components/key-value-editor/editor.js b/packages/insomnia-app/app/ui/components/key-value-editor/editor.js index 9c904c9df1..2fbc42571e 100644 --- a/packages/insomnia-app/app/ui/components/key-value-editor/editor.js +++ b/packages/insomnia-app/app/ui/components/key-value-editor/editor.js @@ -11,6 +11,7 @@ import PromptButton from '../base/prompt-button'; const NAME = 'name'; const VALUE = 'value'; +const DESCRIPTION = 'description'; const ENTER = 13; const BACKSPACE = 8; const UP = 38; @@ -37,7 +38,16 @@ class Editor extends PureComponent { this.state = { pairs: pairs, + displayDescription: false, }; + + // If any pair has a description, display description field. + for (const pair of this.props.pairs) { + if (pair.description) { + this.state.displayDescription = true; + break; + } + } } _setRowRef(n) { @@ -98,6 +108,10 @@ class Editor extends PureComponent { this._focusedField = null; } + _handleBlurDescription() { + this._focusedField = null; + } + _handleFocusName(pair) { this._setFocusedPair(pair); this._focusedField = NAME; @@ -110,6 +124,12 @@ class Editor extends PureComponent { this._rows[pair.id].focusValueEnd(); } + _handleFocusDescription(pair) { + this._setFocusedPair(pair); + this._focusedField = DESCRIPTION; + this._rows[pair.id].focusDescriptionEnd(); + } + _handleAddFromName() { this._focusedField = NAME; this._addPair(); @@ -121,6 +141,11 @@ class Editor extends PureComponent { this._addPair(); } + _handleAddFromDescription() { + this._focusedField = DESCRIPTION; + this._addPair(); + } + _handleKeyDown(pair, e, value) { if (e.metaKey || e.ctrlKey) { return; @@ -168,6 +193,7 @@ class Editor extends PureComponent { const pair = { name: '', value: '', + description: '', }; // Only add ids if we need 'em @@ -289,6 +315,8 @@ class Editor extends PureComponent { row.focusNameEnd(); } else if (this._focusedField === VALUE) { row.focusValueEnd(); + } else if (this._focusedField === DESCRIPTION) { + row.focusDescriptionEnd(); } } @@ -316,6 +344,10 @@ class Editor extends PureComponent { } } + _toggleDescription() { + this.setState({ displayDescription: !this.state.displayDescription }); + } + componentDidUpdate() { this._updateFocus(); } @@ -327,6 +359,7 @@ class Editor extends PureComponent { valueInputType, valuePlaceholder, namePlaceholder, + descriptionPlaceholder, handleRender, handleGetRenderContext, nunjucksPowerUserMode, @@ -352,16 +385,20 @@ class Editor extends PureComponent { index={i} // For dragging ref={this._setRowRef} sortable={sortable} + displayDescription={this.state.displayDescription} namePlaceholder={namePlaceholder} valuePlaceholder={valuePlaceholder} + descriptionPlaceholder={descriptionPlaceholder} valueInputType={valueInputType} onChange={this._handlePairChange} onDelete={this._handlePairDelete} onFocusName={this._handleFocusName} onFocusValue={this._handleFocusValue} + onFocusDescription={this._handleFocusDescription} onKeyDown={this._handleKeyDown} onBlurName={this._handleBlurName} onBlurValue={this._handleBlurValue} + onBlurDescription={this._handleBlurDescription} onMove={this._handleMove} nunjucksPowerUserMode={nunjucksPowerUserMode} isVariableUncovered={isVariableUncovered} @@ -394,16 +431,20 @@ class Editor extends PureComponent { Delete All Items + Toggle Description )} className="key-value-editor__row-wrapper--clicker" + displayDescription={this.state.displayDescription} namePlaceholder={`New ${namePlaceholder}`} valuePlaceholder={`New ${valuePlaceholder}`} + descriptionPlaceholder={`New ${descriptionPlaceholder}`} onFocusName={this._handleAddFromName} onFocusValue={this._handleAddFromValue} + onFocusDescription={this._handleAddFromDescription} allowMultiline={allowMultiline} allowFile={allowFile} - pair={{ name: '', value: '' }} + pair={{ name: '', value: '', description: '' }} /> ) : null} @@ -429,6 +470,7 @@ Editor.propTypes = { maxPairs: PropTypes.number, namePlaceholder: PropTypes.string, valuePlaceholder: PropTypes.string, + descriptionPlaceholder: PropTypes.string, valueInputType: PropTypes.string, disableDelete: PropTypes.bool, onToggleDisable: PropTypes.func, diff --git a/packages/insomnia-app/app/ui/components/key-value-editor/row.js b/packages/insomnia-app/app/ui/components/key-value-editor/row.js index 56667d7c8e..bcbd26c075 100644 --- a/packages/insomnia-app/app/ui/components/key-value-editor/row.js +++ b/packages/insomnia-app/app/ui/components/key-value-editor/row.js @@ -21,6 +21,7 @@ class KeyValueEditorRow extends PureComponent { this._nameInput = null; this._valueInput = null; + this._descriptionInput = null; this.state = { dragDirection: 0, }; @@ -38,6 +39,12 @@ class KeyValueEditorRow extends PureComponent { } } + focusDescriptionEnd() { + if (this._descriptionInput) { + this._descriptionInput.focusEnd(); + } + } + setDragDirection(dragDirection) { if (dragDirection !== this.state.dragDirection) { this.setState({ dragDirection }); @@ -52,6 +59,10 @@ class KeyValueEditorRow extends PureComponent { this._valueInput = n; } + _setDescriptionInputRef(n) { + this._descriptionInput = n; + } + _sendChange(patch) { const pair = Object.assign({}, this.props.pair, patch); this.props.onChange && this.props.onChange(pair); @@ -91,6 +102,10 @@ class KeyValueEditorRow extends PureComponent { this._sendChange({ fileName }); } + _handleDescriptionChange(description) { + this._sendChange({ description }); + } + _handleTypeChange(def) { // Remove newlines if converting to text let value = this.props.pair.value || ''; @@ -113,6 +128,10 @@ class KeyValueEditorRow extends PureComponent { this.props.onFocusValue(this.props.pair, e); } + _handleFocusDescription(e) { + this.props.onFocusDescription(this.props.pair, e); + } + _handleBlurName(e) { if (this.props.onBlurName) { this.props.onBlurName(this.props.pair, e); @@ -125,6 +144,12 @@ class KeyValueEditorRow extends PureComponent { } } + _handleBlurDescription(e) { + if (this.props.onBlurDescription) { + this.props.onBlurDescription(this.props.pair, e); + } + } + _handleDelete() { if (this.props.onDelete) { this.props.onDelete(this.props.pair); @@ -167,6 +192,46 @@ class KeyValueEditorRow extends PureComponent { }); } + renderPairDescription() { + const { + displayDescription, + readOnly, + forceInput, + descriptionPlaceholder, + pair, + handleRender, + handleGetRenderContext, + nunjucksPowerUserMode, + isVariableUncovered, + } = this.props; + + return displayDescription ? ( +
+ +
+ ) : null; + } + renderPairValue() { const { pair, @@ -343,14 +408,12 @@ class KeyValueEditorRow extends PureComponent { />
+ className={classnames('form-control form-control--underlined form-control--wide', { + 'form-control--inactive': pair.disabled, + })}> {this.renderPairValue()}
+ {this.renderPairDescription()} {this.renderPairSelector()} @@ -405,10 +468,13 @@ KeyValueEditorRow.propTypes = { onDelete: PropTypes.func.isRequired, onFocusName: PropTypes.func.isRequired, onFocusValue: PropTypes.func.isRequired, + onFocusDescription: PropTypes.func.isRequired, + displayDescription: PropTypes.bool, index: PropTypes.number.isRequired, pair: PropTypes.shape({ name: PropTypes.string.isRequired, value: PropTypes.string, + description: PropTypes.string, fileName: PropTypes.string, type: PropTypes.string, disabled: PropTypes.bool, @@ -420,6 +486,7 @@ KeyValueEditorRow.propTypes = { onKeyDown: PropTypes.func, onBlurName: PropTypes.func, onBlurValue: PropTypes.func, + onBlurDescription: PropTypes.func, handleRender: PropTypes.func, handleGetRenderContext: PropTypes.func, nunjucksPowerUserMode: PropTypes.bool, @@ -428,6 +495,7 @@ KeyValueEditorRow.propTypes = { handleGetAutocompleteValueConstants: PropTypes.func, namePlaceholder: PropTypes.string, valuePlaceholder: PropTypes.string, + descriptionPlaceholder: PropTypes.string, valueInputType: PropTypes.string, forceInput: PropTypes.bool, allowMultiline: PropTypes.bool, @@ -507,4 +575,8 @@ target.prototype.focusValueEnd = function() { this.decoratedRef.current.decoratedRef.current.focusValueEnd(); }; +target.prototype.focusDescriptionEnd = function() { + this.decoratedRef.current.decoratedRef.current.focusDescriptionEnd(); +}; + export default target; diff --git a/packages/insomnia-app/app/ui/components/request-pane.js b/packages/insomnia-app/app/ui/components/request-pane.js index 13c18ee2d1..97e60f2b52 100644 --- a/packages/insomnia-app/app/ui/components/request-pane.js +++ b/packages/insomnia-app/app/ui/components/request-pane.js @@ -374,6 +374,7 @@ class RequestPane extends React.PureComponent { allowMultiline namePlaceholder="name" valuePlaceholder="value" + descriptionPlaceholder="description" pairs={request.parameters} handleRender={handleRender} handleGetRenderContext={handleGetRenderContext}