Fix issue with duplicating components not replacing IDs on component itself

This commit is contained in:
Andrew Kingston 2022-09-06 09:21:16 +01:00
parent ce89edda48
commit 562576fb83
3 changed files with 33 additions and 34 deletions

View File

@ -182,43 +182,42 @@ export const makeComponentUnique = component => {
// Replace component ID // Replace component ID
const oldId = component._id const oldId = component._id
const newId = Helpers.uuid() const newId = Helpers.uuid()
component._id = newId let definition = JSON.stringify(component)
if (component._children?.length) { // Replace all instances of this ID in HBS bindings
let children = JSON.stringify(component._children) definition = definition.replace(new RegExp(oldId, "g"), newId)
// Replace all instances of this ID in child HBS bindings // Replace all instances of this ID in JS bindings
children = children.replace(new RegExp(oldId, "g"), newId) const bindings = findHBSBlocks(definition)
bindings.forEach(binding => {
// JSON.stringify will have escaped double quotes, so we need
// to account for that
let sanitizedBinding = binding.replace(/\\"/g, '"')
// Replace all instances of this ID in child JS bindings // Check if this is a valid JS binding
const bindings = findHBSBlocks(children) let js = decodeJSBinding(sanitizedBinding)
bindings.forEach(binding => { if (js != null) {
// JSON.stringify will have escaped double quotes, so we need // Replace ID inside JS binding
// to account for that js = js.replace(new RegExp(oldId, "g"), newId)
let sanitizedBinding = binding.replace(/\\"/g, '"')
// Check if this is a valid JS binding // Create new valid JS binding
let js = decodeJSBinding(sanitizedBinding) let newBinding = encodeJSBinding(js)
if (js != null) {
// Replace ID inside JS binding
js = js.replace(new RegExp(oldId, "g"), newId)
// Create new valid JS binding // Replace escaped double quotes
let newBinding = encodeJSBinding(js) newBinding = newBinding.replace(/"/g, '\\"')
// Replace escaped double quotes // Insert new JS back into binding.
newBinding = newBinding.replace(/"/g, '\\"') // A single string replace here is better than a regex as
// the binding contains special characters, and we only need
// to replace a single instance.
definition = definition.replace(binding, newBinding)
}
})
// Insert new JS back into binding. // Recurse on all children
// A single string replace here is better than a regex as component = JSON.parse(definition)
// the binding contains special characters, and we only need return {
// to replace a single instance. ...component,
children = children.replace(binding, newBinding) _children: component._children?.map(makeComponentUnique),
}
})
// Recurse on all children
component._children = JSON.parse(children)
component._children.forEach(makeComponentUnique)
} }
} }

View File

@ -595,7 +595,7 @@ export const getFrontendStore = () => {
// Make new component unique if copying // Make new component unique if copying
if (!cut) { if (!cut) {
makeComponentUnique(componentToPaste) componentToPaste = makeComponentUnique(componentToPaste)
} }
newComponentId = componentToPaste._id newComponentId = componentToPaste._id
@ -905,7 +905,7 @@ export const getFrontendStore = () => {
} }
// Replace block with ejected definition // Replace block with ejected definition
makeComponentUnique(ejectedDefinition) ejectedDefinition = makeComponentUnique(ejectedDefinition)
const index = parent._children.findIndex(x => x._id === componentId) const index = parent._children.findIndex(x => x._id === componentId)
parent._children[index] = ejectedDefinition parent._children[index] = ejectedDefinition
nextSelectedComponentId = ejectedDefinition._id nextSelectedComponentId = ejectedDefinition._id

View File

@ -38,7 +38,7 @@
let duplicateScreen = Helpers.cloneDeep(screen) let duplicateScreen = Helpers.cloneDeep(screen)
delete duplicateScreen._id delete duplicateScreen._id
delete duplicateScreen._rev delete duplicateScreen._rev
makeComponentUnique(duplicateScreen.props) duplicateScreen.props = makeComponentUnique(duplicateScreen.props)
// Attach the new name and URL // Attach the new name and URL
duplicateScreen.routing.route = sanitizeUrl(screenUrl) duplicateScreen.routing.route = sanitizeUrl(screenUrl)