Handle changes via JSONPatch
This commit is contained in:
parent
e66ff70ac4
commit
4d2eb28eb3
|
@ -1,6 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import JSONEditor from './JSONEditor.svelte'
|
import JSONEditor from './JSONEditor.svelte'
|
||||||
import { beforeUpdate, afterUpdate } from 'svelte'
|
|
||||||
|
|
||||||
let json = {
|
let json = {
|
||||||
'array': [1, 2, 3, {
|
'array': [1, 2, 3, {
|
||||||
|
@ -47,9 +46,6 @@
|
||||||
|
|
||||||
console.time('load editor')
|
console.time('load editor')
|
||||||
|
|
||||||
beforeUpdate(() => console.time('render app'))
|
|
||||||
afterUpdate(() => console.timeEnd('render app'))
|
|
||||||
|
|
||||||
function handleChangeFiles (event) {
|
function handleChangeFiles (event) {
|
||||||
console.log('handleChangeFiles', event.target.files)
|
console.log('handleChangeFiles', event.target.files)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { faSearch } from '@fortawesome/free-solid-svg-icons'
|
import { faSearch } from '@fortawesome/free-solid-svg-icons'
|
||||||
import Node from './JSONNode.svelte'
|
import Node from './JSONNode.svelte'
|
||||||
import { search } from './search'
|
import { search } from './search'
|
||||||
import { beforeUpdate, afterUpdate } from 'svelte'
|
import { immutableJSONPatch } from './utils/immutableJSONPatch'
|
||||||
|
|
||||||
export let json = {}
|
export let json = {}
|
||||||
export let onChange = () => {}
|
export let onChange = () => {}
|
||||||
|
@ -17,8 +17,9 @@
|
||||||
json = newJson
|
json = newJson
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeUpdate(() => console.time('render JSONEditor'))
|
function getPath () {
|
||||||
afterUpdate(() => console.timeEnd('render JSONEditor'))
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
function doSearch (json, searchText) {
|
function doSearch (json, searchText) {
|
||||||
console.time('search')
|
console.time('search')
|
||||||
|
@ -38,16 +39,17 @@
|
||||||
|
|
||||||
function handleChangeValue (value, key) {
|
function handleChangeValue (value, key) {
|
||||||
// console.log('handleChangeValue', value, key)
|
// console.log('handleChangeValue', value, key)
|
||||||
json = value
|
// json = value
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInputTextArea (event) {
|
/**
|
||||||
console.log('on:input')
|
* @param {JSONPatchDocument} operations
|
||||||
try {
|
*/
|
||||||
json = JSON.parse(event.target.value)
|
function handleChange (operations) {
|
||||||
} catch (err) {
|
console.log('handleChange', operations)
|
||||||
console.error(err)
|
|
||||||
}
|
// TODO: store changes in history
|
||||||
|
json = immutableJSONPatch(json, operations).json
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -62,6 +64,8 @@
|
||||||
expanded={true}
|
expanded={true}
|
||||||
onChangeKey={handleChangeKey}
|
onChangeKey={handleChangeKey}
|
||||||
onChangeValue={handleChangeValue}
|
onChangeValue={handleChangeValue}
|
||||||
|
onChange={handleChange}
|
||||||
|
getParentPath={getPath}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,14 +8,24 @@
|
||||||
import { updateProps } from './utils/updateProps.js'
|
import { updateProps } from './utils/updateProps.js'
|
||||||
import { unescapeHTML } from './utils/stringUtils'
|
import { unescapeHTML } from './utils/stringUtils'
|
||||||
import { getInnerText } from './utils/domUtils'
|
import { getInnerText } from './utils/domUtils'
|
||||||
|
import { compileJSONPointer } from './utils/jsonPointer'
|
||||||
|
|
||||||
export let key = undefined
|
export let key = undefined // only applicable for object properties
|
||||||
|
export let index = undefined // only applicable for array items
|
||||||
export let value
|
export let value
|
||||||
export let searchResult
|
export let searchResult
|
||||||
|
export let onChange
|
||||||
export let onChangeKey
|
export let onChangeKey
|
||||||
export let onChangeValue
|
|
||||||
export let expanded = false
|
export let expanded = false
|
||||||
|
|
||||||
|
export let getParentPath
|
||||||
|
|
||||||
|
function getPath () {
|
||||||
|
return key !== undefined
|
||||||
|
? getParentPath().concat(key)
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
|
||||||
const DEFAULT_LIMIT = 100
|
const DEFAULT_LIMIT = 100
|
||||||
const escapeUnicode = false // TODO: pass via options
|
const escapeUnicode = false // TODO: pass via options
|
||||||
|
|
||||||
|
@ -90,7 +100,17 @@
|
||||||
|
|
||||||
function handleKeyInput (event) {
|
function handleKeyInput (event) {
|
||||||
const newKey = unescapeHTML(getInnerText(event.target))
|
const newKey = unescapeHTML(getInnerText(event.target))
|
||||||
|
|
||||||
|
// TODO: replace the onChangeKey callback with gobally managed JSONNode id's,
|
||||||
|
// which are kept in sync with the json itself using JSONPatch
|
||||||
onChangeKey(newKey, key)
|
onChangeKey(newKey, key)
|
||||||
|
|
||||||
|
const parentPath = getParentPath()
|
||||||
|
onChange([{
|
||||||
|
op: 'move',
|
||||||
|
from: compileJSONPointer(parentPath.concat(key)),
|
||||||
|
path: compileJSONPointer(parentPath.concat(newKey))
|
||||||
|
}])
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyBlur () {
|
function handleKeyBlur () {
|
||||||
|
@ -101,7 +121,12 @@
|
||||||
function handleValueInput (event) {
|
function handleValueInput (event) {
|
||||||
const valueText = unescapeHTML(getInnerText(event.target))
|
const valueText = unescapeHTML(getInnerText(event.target))
|
||||||
const newValue = stringConvert(valueText) // TODO: implement support for type "string"
|
const newValue = stringConvert(valueText) // TODO: implement support for type "string"
|
||||||
onChangeValue(newValue, key)
|
|
||||||
|
onChange([{
|
||||||
|
op: 'replace',
|
||||||
|
path: compileJSONPointer(getPath()),
|
||||||
|
value: newValue
|
||||||
|
}])
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleValueBlur () {
|
function handleValueBlur () {
|
||||||
|
@ -129,15 +154,6 @@
|
||||||
|
|
||||||
function handleChangeKey (newChildKey, oldChildKey) {
|
function handleChangeKey (newChildKey, oldChildKey) {
|
||||||
if (type === 'object') {
|
if (type === 'object') {
|
||||||
const updatedValue = {}
|
|
||||||
Object.keys(value).forEach(childKey => {
|
|
||||||
if (childKey === oldChildKey) {
|
|
||||||
updatedValue[newChildKey] = value[childKey]
|
|
||||||
} else {
|
|
||||||
updatedValue[childKey] = value[childKey]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const index = props.findIndex(item => item.key === oldChildKey)
|
const index = props.findIndex(item => item.key === oldChildKey)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
// we use splice here to replace the old key with the new new one
|
// we use splice here to replace the old key with the new new one
|
||||||
|
@ -150,21 +166,6 @@
|
||||||
key: newChildKey
|
key: newChildKey
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeValue(updatedValue, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleChangeValue (childValue, childKey) {
|
|
||||||
// FIXME: use an immutability setIn function here
|
|
||||||
if (type === 'array') {
|
|
||||||
const updatedValue = [...value]
|
|
||||||
updatedValue[childKey] = childValue
|
|
||||||
onChangeValue(updatedValue, key)
|
|
||||||
} else if (type === 'object') {
|
|
||||||
const updatedValue = { ...value }
|
|
||||||
updatedValue[childKey] = childValue
|
|
||||||
onChangeValue(updatedValue, key)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +211,8 @@
|
||||||
value={item}
|
value={item}
|
||||||
searchResult={searchResult ? searchResult[index] : undefined}
|
searchResult={searchResult ? searchResult[index] : undefined}
|
||||||
onChangeKey={handleChangeKey}
|
onChangeKey={handleChangeKey}
|
||||||
onChangeValue={handleChangeValue}
|
onChange={onChange}
|
||||||
|
getParentPath={getPath}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{#if limited}
|
{#if limited}
|
||||||
|
@ -259,7 +261,8 @@
|
||||||
value={value[prop.key]}
|
value={value[prop.key]}
|
||||||
searchResult={searchResult ? searchResult[prop.key] : undefined}
|
searchResult={searchResult ? searchResult[prop.key] : undefined}
|
||||||
onChangeKey={handleChangeKey}
|
onChangeKey={handleChangeKey}
|
||||||
onChangeValue={handleChangeValue}
|
onChange={onChange}
|
||||||
|
getParentPath={getPath}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue