// eslint-disable-next-line filenames/match-exported
import React, {PropTypes, PureComponent} from 'react';
import ReactDOM from 'react-dom';
import autobind from 'autobind-decorator';
import {DragSource, DropTarget} from 'react-dnd';
import classnames from 'classnames';
import FileInputButton from '../base/file-input-button';
import {Dropdown, DropdownButton, DropdownItem} from '../base/dropdown/index';
import PromptButton from '../base/prompt-button';
import CodePromptModal from '../modals/code-prompt-modal';
import Button from '../base/button';
import OneLineEditor from '../codemirror/one-line-editor';
import {showModal} from '../modals/index';
import {describeByteSize} from '../../../common/misc';
@autobind
class KeyValueEditorRow extends PureComponent {
constructor (props) {
super(props);
this._nameInput = null;
this._valueInput = null;
this.state = {
dragDirection: 0
};
}
focusNameEnd () {
if (this._nameInput) {
this._nameInput.focusEnd();
}
}
focusValueEnd () {
if (this._valueInput) {
this._valueInput.focusEnd();
}
}
setDragDirection (dragDirection) {
if (dragDirection !== this.state.dragDirection) {
this.setState({dragDirection});
}
}
_setNameInputRef (n) {
this._nameInput = n;
}
_setValueInputRef (n) {
this._valueInput = n;
}
_sendChange (patch) {
const pair = Object.assign({}, this.props.pair, patch);
this.props.onChange && this.props.onChange(pair);
}
_handleNameChange (name) {
this._sendChange({name});
}
_handleValuePaste (e) {
const value = e.clipboardData.getData('text/plain');
if (value && value.includes('\n')) {
e.preventDefault();
// Insert the pasted text into the current selection. Unfortunately, this
// is the easiest way to do this.
const currentValue = this._valueInput.getValue();
const prefix = currentValue.slice(0, this._valueInput.getSelectionStart());
const suffix = currentValue.slice(this._valueInput.getSelectionEnd());
const finalValue = `${prefix}${value}${suffix}`;
// Update type and value
this._handleTypeChange({type: 'text', multiline: 'text/plain'});
this._handleValueChange(finalValue);
}
}
_handleValueChange (value) {
this._sendChange({value});
}
_handleFileNameChange (fileName) {
this._sendChange({fileName});
}
_handleTypeChange (def) {
// Remove newlines if converting to text
let value = this.props.pair.value || '';
if (def.type === 'text' && !def.multiline && value.includes('\n')) {
value = value.replace(/\n/g, '');
}
this._sendChange({type: def.type, multiline: def.multiline, value});
}
_handleDisableChange (disabled) {
this._sendChange({disabled});
}
_handleFocusName (e) {
this.props.onFocusName(this.props.pair, e);
}
_handleFocusValue (e) {
this.props.onFocusValue(this.props.pair, e);
}
_handleBlurName (e) {
if (this.props.onBlurName) {
this.props.onBlurName(this.props.pair, e);
}
}
_handleBlurValue (e) {
if (this.props.onBlurName) {
this.props.onBlurValue(this.props.pair, e);
}
}
_handleDelete () {
if (this.props.onDelete) {
this.props.onDelete(this.props.pair);
}
}
_handleKeyDown (e, value) {
if (this.props.onKeyDown) {
this.props.onKeyDown(this.props.pair, e, value);
}
}
_handleAutocompleteNames () {
const {handleGetAutocompleteNameConstants} = this.props;
if (handleGetAutocompleteNameConstants) {
return handleGetAutocompleteNameConstants(this.props.pair);
}
}
_handleAutocompleteValues () {
const {handleGetAutocompleteValueConstants} = this.props;
if (handleGetAutocompleteValueConstants) {
return handleGetAutocompleteValueConstants(this.props.pair);
}
}
_handleEditMultiline () {
const {pair, handleRender, handleGetRenderContext} = this.props;
showModal(CodePromptModal, {
submitName: 'Done',
title: `Edit ${pair.name}`,
defaultValue: pair.value,
onChange: this._handleValueChange,
enableRender: handleRender || handleGetRenderContext,
onModeChange: mode => {
this._handleTypeChange(Object.assign({}, pair, {multiline: mode}));
}
});
}
renderPairValue () {
const {
pair,
readOnly,
forceInput,
valueInputType,
valuePlaceholder,
handleRender,
handleGetRenderContext
} = this.props;
if (pair.type === 'file') {
return (