Fix appending `... (copy)` suffix when replacing keys with new keys having the same name(s)

This commit is contained in:
Jos de Jong 2020-07-12 11:13:06 +02:00
parent fb3a9cdf36
commit 89fc4070a2
2 changed files with 19 additions and 12 deletions

View File

@ -1,6 +1,4 @@
import first from 'lodash/first' import { first, initial, last, pickBy } from 'lodash-es'
import initial from 'lodash/initial'
import last from 'lodash/last'
import { getIn } from './utils/immutabilityHelpers' import { getIn } from './utils/immutabilityHelpers'
import { compileJSONPointer } from './utils/jsonPointer' import { compileJSONPointer } from './utils/jsonPointer'
import { findUniqueName } from './utils/stringUtils' import { findUniqueName } from './utils/stringUtils'
@ -149,13 +147,18 @@ export function replace (json, paths, values, nextKeys) { // TODO: find a bette
] ]
} }
else { // parent is Object else { // parent is Object
// if we're going to replace an existing object with key "a" with a new
// key "a", we must not create a new unique name "a (copy)".
const removeKeys = new Set(paths.map(path => last(path)))
const parentWithoutRemovedKeys = pickBy(parent, (value, key) => !removeKeys.has(key))
return [ return [
// remove operations // remove operations
...removeAll(paths), ...removeAll(paths),
// insert operations // insert operations
...values.map(entry => { ...values.map(entry => {
const newProp = findUniqueName(entry.key, parent) const newProp = findUniqueName(entry.key, parentWithoutRemovedKeys)
return { return {
op: 'add', op: 'add',
path: compileJSONPointer(parentPath.concat(newProp)), path: compileJSONPointer(parentPath.concat(newProp)),

View File

@ -78,19 +78,23 @@ export function patchProps (state, operations) {
} }
if (operation.op === 'add') { if (operation.op === 'add') {
const path = parseJSONPointer(operation.path) const pathTo = parseJSONPointer(operation.path)
const parentPath = initial(path) const parentPath = initial(pathTo)
const key = last(pathTo)
const props = getIn(updatedState, parentPath.concat(STATE_PROPS)) const props = getIn(updatedState, parentPath.concat(STATE_PROPS))
if (props) { if (props) {
const index = props.findIndex(item => item.key === key)
if (index === -1) {
const newProp = { const newProp = {
id: uniqueId(), id: uniqueId(),
key: last(path) key
} }
const updatedProps = insertAt(props, [props.length], newProp) const updatedProps = insertAt(props, [props.length], newProp)
updatedState = setIn(updatedState, parentPath.concat([STATE_PROPS]), updatedProps) updatedState = setIn(updatedState, parentPath.concat([STATE_PROPS]), updatedProps)
} }
} }
}
}) })
return updatedState return updatedState