Skip to content

Commit

Permalink
console: Refactor key value map component
Browse files Browse the repository at this point in the history
  • Loading branch information
ryaplots committed Aug 2, 2023
1 parent f9f4541 commit e2d3d06
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 222 deletions.
202 changes: 95 additions & 107 deletions pkg/webui/components/key-value-map/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import React from 'react'
import bind from 'autobind-decorator'
import React, { useCallback } from 'react'
import { defineMessages } from 'react-intl'
import classnames from 'classnames'

Expand All @@ -27,117 +26,104 @@ const m = defineMessages({
deleteEntry: 'Delete entry',
})

class Entry extends React.Component {
static propTypes = {
readOnly: PropTypes.bool,
}
static defaultProps = { readOnly: false }

_getKeyInputName() {
const { name, index } = this.props

return `${name}[${index}].key`
}

_getValueInputName() {
const { name, index } = this.props

return `${name}[${index}].value`
}

@bind
handleRemoveButtonClicked(event) {
const { onRemoveButtonClick, index } = this.props

onRemoveButtonClick(index, event)
}

@bind
handleKeyChanged(newKey) {
const { onChange, index } = this.props

onChange(index, { key: newKey })
}

@bind
handleValueChanged(newValue) {
const { onChange, index } = this.props

onChange(index, { value: newValue })
}

@bind
handleBlur(event) {
const { name, onBlur, value } = this.props

const { relatedTarget } = event
const nextTarget = relatedTarget || {}

if (
nextTarget.name !== this._getKeyInputName() &&
nextTarget.name !== this._getValueInputName()
) {
onBlur({
target: {
name,
value,
},
})
}
}

render() {
const {
keyPlaceholder,
valuePlaceholder,
value,
indexAsKey,
readOnly,
inputElement: InputElement,
additionalInputProps,
} = this.props

return (
<div className={style.entriesRow}>
{!indexAsKey && (
<InputElement
data-test-id={this._getKeyInputName()}
className={style.input}
name={this._getKeyInputName()}
placeholder={keyPlaceholder}
type="text"
onChange={this.handleKeyChanged}
onBlur={this.handleBlur}
value={value.key}
readOnly={readOnly}
code
{...additionalInputProps}
/>
)}
const Entry = ({
readOnly,
name,
value,
index,
onRemoveButtonClick,
onChange,
onBlur,
inputElement,
indexAsKey,
valuePlaceholder,
keyPlaceholder,
additionalInputProps,
}) => {
const _getKeyInputName = useCallback(() => `${name}[${index}].key`, [index, name])

const _getValueInputName = useCallback(() => `${name}[${index}].value`, [index, name])

const handleRemoveButtonClicked = useCallback(
event => {
onRemoveButtonClick(index, event)
},
[index, onRemoveButtonClick],
)

const handleKeyChanged = useCallback(
newKey => {
onChange(index, { key: newKey })
},
[index, onChange],
)

const handleValueChanged = useCallback(
newValue => {
onChange(index, { value: newValue })
},
[index, onChange],
)

const handleBlur = useCallback(
event => {
const { relatedTarget } = event
const nextTarget = relatedTarget || {}

if (nextTarget.name !== _getKeyInputName() && nextTarget.name !== _getValueInputName()) {
onBlur({
target: {
name,
value,
},
})
}
},
[onBlur, name, value, _getKeyInputName, _getValueInputName],
)

const { InputElement } = inputElement

return (
<div className={style.entriesRow}>
{!indexAsKey && (
<InputElement
data-test-id={this._getValueInputName()}
className={classnames(style.input, { [style.inputIndexAsKey]: indexAsKey })}
name={this._getValueInputName()}
placeholder={valuePlaceholder}
data-test-id={_getKeyInputName()}
className={style.input}
name={_getKeyInputName()}
placeholder={keyPlaceholder}
type="text"
onChange={this.handleValueChanged}
onBlur={this.handleBlur}
value={indexAsKey ? value : value.value}
onChange={handleKeyChanged}
onBlur={handleBlur}
value={value.key}
readOnly={readOnly}
code
{...additionalInputProps}
/>
<Button
type="button"
onClick={this.handleRemoveButtonClicked}
icon="delete"
title={m.deleteEntry}
disabled={readOnly}
danger
/>
</div>
)
}
)}
<InputElement
data-test-id={_getValueInputName()}
className={classnames(style.input, { [style.inputIndexAsKey]: indexAsKey })}
name={_getValueInputName()}
placeholder={valuePlaceholder}
type="text"
onChange={handleValueChanged}
onBlur={handleBlur}
value={indexAsKey ? value : value.value}
readOnly={readOnly}
code
{...additionalInputProps}
/>
<Button
type="button"
onClick={handleRemoveButtonClicked}
icon="delete"
title={m.deleteEntry}
disabled={readOnly}
danger
/>
</div>
)
}

Entry.propTypes = {
Expand All @@ -150,6 +136,7 @@ Entry.propTypes = {
onBlur: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
onRemoveButtonClick: PropTypes.func.isRequired,
readOnly: PropTypes.bool,
value: PropTypes.oneOfType([
PropTypes.shape({
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
Expand All @@ -162,6 +149,7 @@ Entry.propTypes = {

Entry.defaultProps = {
value: undefined,
readOnly: false,
}

export default Entry
Loading

0 comments on commit e2d3d06

Please sign in to comment.