Implemented duplicate for multiple nodes
This commit is contained in:
parent
dd989f9a64
commit
cb354f2331
|
@ -92,37 +92,44 @@ export function changeType (data, path, type) {
|
|||
* and object property
|
||||
*
|
||||
* @param {ESON} data
|
||||
* @param {Path} path
|
||||
* @param {ESONSelection} selection
|
||||
* @return {Array}
|
||||
*/
|
||||
export function duplicate (data, path) {
|
||||
export function duplicate (data, selection) {
|
||||
// console.log('duplicate', path)
|
||||
|
||||
const parentPath = path.slice(0, path.length - 1)
|
||||
const rootPath = findRootPath(selection)
|
||||
const start = selection.start.path[rootPath.length]
|
||||
const end = selection.end.path[rootPath.length]
|
||||
const root = getIn(data, toEsonPath(data, rootPath))
|
||||
const { maxIndex } = findSelectionIndices(root, start, end)
|
||||
const paths = pathsFromSelection(data, selection)
|
||||
|
||||
const esonPath = toEsonPath(data, parentPath)
|
||||
const parent = getIn(data, esonPath)
|
||||
|
||||
if (parent.type === 'Array') {
|
||||
const index = parseInt(path[path.length - 1]) + 1
|
||||
return [{
|
||||
if (root.type === 'Array') {
|
||||
return paths.map((path, offset) => ({
|
||||
op: 'copy',
|
||||
from: compileJSONPointer(path),
|
||||
path: compileJSONPointer(parentPath.concat(index))
|
||||
}]
|
||||
path: compileJSONPointer(rootPath.concat(maxIndex + offset))
|
||||
}))
|
||||
}
|
||||
else { // object.type === 'Object'
|
||||
const prop = path[path.length - 1]
|
||||
const newProp = findUniqueName(prop, parent.props.map(p => p.name))
|
||||
const { maxIndex } = findSelectionIndices(root, start, end)
|
||||
const nextProp = root.props && root.props[maxIndex]
|
||||
const before = nextProp ? nextProp.name : null
|
||||
|
||||
return [{
|
||||
return paths.map(path => {
|
||||
const prop = last(path)
|
||||
const newProp = findUniqueName(prop, root.props.map(p => p.name))
|
||||
|
||||
return {
|
||||
op: 'copy',
|
||||
from: compileJSONPointer(path),
|
||||
path: compileJSONPointer(parentPath.concat(newProp)),
|
||||
path: compileJSONPointer(rootPath.concat(newProp)),
|
||||
jsoneditor: {
|
||||
before: findNextProp(parent, prop)
|
||||
before
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,7 +233,7 @@ export function insertBefore (data, path, values) { // TODO: find a better name
|
|||
* and object property
|
||||
*
|
||||
* @param {ESON} data
|
||||
* @param {Selection} selection
|
||||
* @param {ESONSelection} selection
|
||||
* @param {Array.<{name?: string, value: JSONType, type?: ESONType}>} values
|
||||
* @return {Array}
|
||||
*/
|
||||
|
@ -235,10 +242,8 @@ export function replace (data, selection, values) { // TODO: find a better name
|
|||
const rootPath = findRootPath(selection)
|
||||
const start = selection.start.path[rootPath.length]
|
||||
const end = selection.end.path[rootPath.length]
|
||||
console.log('rootPath', rootPath, start, end)
|
||||
const root = getIn(data, toEsonPath(data, rootPath))
|
||||
const { minIndex, maxIndex } = findSelectionIndices(root, start, end)
|
||||
console.log('selection', minIndex, maxIndex)
|
||||
|
||||
if (root.type === 'Array') {
|
||||
const removeActions = removeAll(pathsFromSelection(data, selection))
|
||||
|
|
|
@ -72,6 +72,7 @@ export default class TreeMode extends Component {
|
|||
'cut': this.handleKeyDownCut,
|
||||
'copy': this.handleKeyDownCopy,
|
||||
'paste': this.handleKeyDownPaste,
|
||||
'duplicate': this.handleKeyDownDuplicate,
|
||||
'undo': this.handleUndo,
|
||||
'redo': this.handleRedo,
|
||||
'find': this.handleFocusFind,
|
||||
|
@ -372,11 +373,11 @@ export default class TreeMode extends Component {
|
|||
this.focusToNext(parentPath)
|
||||
}
|
||||
|
||||
handleDuplicate = (path) => {
|
||||
this.handlePatch(duplicate(this.state.data, path))
|
||||
|
||||
// apply focus to the duplicated node
|
||||
this.focusToNext(path)
|
||||
handleDuplicate = () => {
|
||||
if (this.state.selection) {
|
||||
this.handlePatch(duplicate(this.state.data, this.state.selection))
|
||||
// TODO: focus to duplicated selection
|
||||
}
|
||||
}
|
||||
|
||||
handleRemove = (path) => {
|
||||
|
@ -455,6 +456,17 @@ export default class TreeMode extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleKeyDownDuplicate = (event) => {
|
||||
const path = this.findDataPathFromElement(event.target)
|
||||
if (path) {
|
||||
const selection = { start: {path}, end: {path} }
|
||||
this.handlePatch(duplicate(this.state.data, selection))
|
||||
|
||||
// apply focus to the duplicated node
|
||||
this.focusToNext(path)
|
||||
}
|
||||
}
|
||||
|
||||
handleCut = () => {
|
||||
const selection = this.state.selection
|
||||
if (selection && selection.start && selection.end) {
|
||||
|
|
|
@ -53,42 +53,42 @@ const CREATE_TYPE = {
|
|||
duplicate: (path, events) => h('button', {
|
||||
key: 'duplicate',
|
||||
className: MENU_ITEM_CLASS_NAME,
|
||||
onClick: () => events.onDuplicate(path),
|
||||
onClick: () => events.onDuplicate(),
|
||||
title: 'Duplicate'
|
||||
}, 'Duplicate'),
|
||||
|
||||
cut: (path, events) => h('button', {
|
||||
key: 'cut',
|
||||
className: MENU_ITEM_CLASS_NAME,
|
||||
onClick: () => events.onCut(path),
|
||||
onClick: () => events.onCut(),
|
||||
title: 'Cut'
|
||||
}, 'Cut'),
|
||||
|
||||
copy: (path, events) => h('button', {
|
||||
key: 'copy',
|
||||
className: MENU_ITEM_CLASS_NAME,
|
||||
onClick: () => events.onCopy(path),
|
||||
onClick: () => events.onCopy(),
|
||||
title: 'Copy'
|
||||
}, 'Copy'),
|
||||
|
||||
paste: (path, events) => h('button', {
|
||||
key: 'paste',
|
||||
className: MENU_ITEM_CLASS_NAME,
|
||||
onClick: () => events.onPaste(path),
|
||||
onClick: () => events.onPaste(),
|
||||
title: 'Paste'
|
||||
}, 'Paste'),
|
||||
|
||||
remove: (path, events) => h('button', {
|
||||
key: 'remove',
|
||||
className: MENU_ITEM_CLASS_NAME,
|
||||
onClick: () => events.onRemove(null), // do not pass path: we want to remove selection
|
||||
onClick: () => events.onRemove(),
|
||||
title: 'Remove'
|
||||
}, 'Remove'),
|
||||
|
||||
insertStructure: (path, events) => h('button', {
|
||||
key: 'insertStructure',
|
||||
className: MENU_ITEM_CLASS_NAME,
|
||||
onClick: () => events.onInsertStructure(path),
|
||||
onClick: () => events.onInsertStructure(),
|
||||
title: 'Insert a new object with the same data structure as the item above'
|
||||
}, 'Insert structure'),
|
||||
|
||||
|
|
Loading…
Reference in New Issue