Skip to content

Commit

Permalink
fix(NormalizeField): Adjust for changes from backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
binh-dam-ibigroup committed Jun 16, 2021
1 parent 93c1062 commit 5a981d6
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 19 deletions.
70 changes: 62 additions & 8 deletions lib/manager/components/transform/NormalizeField.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow

import Icon from '@conveyal/woonerf/components/icon'
import { isEqual } from 'lodash'
import React, { Component } from 'react'
import {
Button,
Expand All @@ -24,15 +25,44 @@ import type {
} from '../../../types'

type State = {
activeEditingIndex: number
activeEditingIndex: number,
// Holds the contents that should be shown in the SubstitutionRow component.
activeSubstitution: ?Substitution,
// Last edited contents.
previousEditingIndex: number,
previousSubstitution: ?Substitution
}

/**
* Determines whether two substitutions are equal (except for the valid field).
*/
function areEqual (sub1: ?Substitution, sub2: ?Substitution): boolean {
if (!sub1 || !sub2) return false
return isEqual(
{
description: sub1.description,
normalizeSpace: sub1.normalizeSpace,
pattern: sub1.pattern,
replacement: sub1.replacement
},
{
description: sub2.description,
normalizeSpace: sub2.normalizeSpace,
pattern: sub2.pattern,
replacement: sub2.replacement
}
)
}

/**
* Component that renders input fields for the NormalizeFieldTransformation.
*/
export default class NormalizeField extends Component<TransformProps<NormalizeFieldFields>, State> {
state = {
activeEditingIndex: -1
activeEditingIndex: -1,
activeSubstitution: null,
previousEditingIndex: -1,
previousSubstitution: null
}

componentDidMount () {
Expand All @@ -42,6 +72,21 @@ export default class NormalizeField extends Component<TransformProps<NormalizeFi
componentDidUpdate (prevProps: TransformProps<NormalizeFieldFields>) {
if (prevProps.transformation !== this.props.transformation) {
this._updateErrors()

// If user entered an invalid substitution pattern and clicks save,
// it will be rejected and the values entered will be lost.
// To avoid that, keep the new row visible and in editing state.
const { previousEditingIndex, previousSubstitution: editedSubstitution } = this.state
const loadedSubstitution = this.props.transformation.substitutions[previousEditingIndex]
if (previousEditingIndex !== -1 && !areEqual(editedSubstitution, loadedSubstitution)) {
this.setState({
activeEditingIndex: previousEditingIndex,
activeSubstitution: {
...editedSubstitution,
valid: false
}
})
}
}
}

Expand All @@ -60,12 +105,17 @@ export default class NormalizeField extends Component<TransformProps<NormalizeFi
_onChangeSubstitution = (substitution: Substitution, index: number) => {
const newSubstitutions = [].concat(this.props.transformation.substitutions)
newSubstitutions[index] = substitution
this.setState({
activeSubstitution: null,
previousSubstitution: substitution
})
this._updateTransformation({substitutions: newSubstitutions})
}

_onRemoveSubstitution = (index: number) => {
const newSubstitutions = [].concat(this.props.transformation.substitutions)
newSubstitutions.splice(index, 1)
this.setState({ previousEditingIndex: -1 })
this._updateTransformation({substitutions: newSubstitutions})
}

Expand Down Expand Up @@ -101,7 +151,11 @@ export default class NormalizeField extends Component<TransformProps<NormalizeFi
}

_onEndEditSubstitution = () => {
this.setState({ activeEditingIndex: -1 })
this.setState({
activeEditingIndex: -1,
activeSubstitution: null,
previousEditingIndex: this.state.activeEditingIndex
})
}

/**
Expand Down Expand Up @@ -129,7 +183,7 @@ export default class NormalizeField extends Component<TransformProps<NormalizeFi

render () {
const { index, transformation } = this.props
const { activeEditingIndex } = this.state
const { activeEditingIndex, activeSubstitution } = this.state
const {
capitalizationExceptions,
capitalize,
Expand Down Expand Up @@ -233,7 +287,7 @@ export default class NormalizeField extends Component<TransformProps<NormalizeFi
onChange={this._onChangeSubstitution}
onEndEdit={this._onEndEditSubstitution}
onRemove={this._onRemoveSubstitution}
substitution={s}
substitution={activeEditingIndex === i ? (activeSubstitution || s) : s}
/>
))}
{activeEditingIndex === substitutions.length &&
Expand All @@ -244,10 +298,10 @@ export default class NormalizeField extends Component<TransformProps<NormalizeFi
key={activeEditingIndex}
onChange={this._onChangeSubstitution}
onEndEdit={this._onEndEditSubstitution}
substitution={{
invalid: false,
substitution={activeSubstitution || {
pattern: '',
replacement: ''
replacement: '',
valid: true
}}
/>
}
Expand Down
18 changes: 9 additions & 9 deletions lib/manager/components/transform/SubstitutionRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ const buttonGroupStyle = { width: '60px' }
* Extract just the subset of fields to build the state variable.
*/
function extractStateFields (props: Props): Substitution {
const { description, invalid, normalizeSpace, pattern, replacement } = props.substitution
const { description, normalizeSpace, pattern, replacement, valid } = props.substitution
return {
description: description || '',
invalid,
normalizeSpace,
normalizeSpace: normalizeSpace || false,
pattern,
replacement
replacement,
valid
}
}

Expand All @@ -50,7 +50,7 @@ export function isSubstitutionBlank (substitution: Substitution) {
* @returns true if the given substitution is marked invalid by the backend, false otherwise.
*/
export function isSubstitutionInvalid (substitution: Substitution) {
return substitution.invalid
return !substitution.valid
}

/**
Expand All @@ -66,7 +66,7 @@ export default class SubstitutionRow extends Component<Props, Substitution> {
const { index, substitution } = this.props

// If a new substition is associated with this component, reset its state.
if (prevProps.index !== index || !isEqual(prevProps.substitution, substitution)) {
if (prevProps.index !== index || prevProps.substitution !== substitution) {
this.setState(extractStateFields(this.props))
}
}
Expand Down Expand Up @@ -146,12 +146,12 @@ export default class SubstitutionRow extends Component<Props, Substitution> {

render () {
const { activeEditingIndex, substitution: originalSubstitution } = this.props
const { description, invalid, normalizeSpace, pattern, replacement } = this.state
const { description, normalizeSpace, pattern, replacement, valid } = this.state
const regexTestLink = `https://regexr.com/?expression=${encodeURIComponent(pattern)}&text=${STRING_FOR_REGEXR_TEST}`
const isEditing = this._isEditing()
const allowEdit = activeEditingIndex === -1
const isPatternBlank = isSubstitutionBlank(this.state)
const isPatternInvalid = invalid && pattern === originalSubstitution.pattern
const isPatternInvalid = !valid && pattern === originalSubstitution.pattern
const isEditingInvalid = isPatternBlank || isPatternInvalid
let validationMessage = null
if (isPatternBlank) {
Expand All @@ -166,7 +166,7 @@ export default class SubstitutionRow extends Component<Props, Substitution> {
const rowClassName = `substitution-row ${editingClassName} ${allowEditClassName}`

// Override style for inputs with invalid search patterns.
const patternStyleOverride = isPatternInvalid ? { borderColor: 'inherit' } : null
const patternStyleOverride = isPatternInvalid ? { borderColor: '#a94442' } : null

return (
<tr className={rowClassName}>
Expand Down
4 changes: 2 additions & 2 deletions lib/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,10 @@ export type FetchFrequency = $Values<typeof FETCH_FREQUENCIES>

export type Substitution = {
description?: string,
invalid: boolean,
normalizeSpace?: boolean,
pattern: string,
replacement: string
replacement: string,
valid: boolean
}

export type NormalizeFieldFields = {
Expand Down

0 comments on commit 5a981d6

Please sign in to comment.