Implement methods `expandAll`, `collapseAll`, and Ctrl+Click on expand button

This commit is contained in:
josdejong 2020-06-02 21:41:59 +02:00
parent 40accb3f39
commit 61d91c2f9c
3 changed files with 35 additions and 15 deletions

View File

@ -11,7 +11,12 @@
import { faSearch, faUndo, faRedo } from '@fortawesome/free-solid-svg-icons'
import { createHistory } from './history.js'
import Node from './JSONNode.svelte'
import { existsIn, getIn, setIn } from './utils/immutabilityHelpers.js'
import {
existsIn,
getIn,
setIn,
updateIn
} from './utils/immutabilityHelpers.js'
import { compileJSONPointer, parseJSONPointer } from './utils/jsonPointer.js'
import { keyComboFromEvent } from './utils/keyBindings.js'
import { flattenSearch, search } from './utils/search.js'
@ -54,6 +59,14 @@
})
let historyState = history.getState()
export function expandAll () {
state = syncState(doc, state, [], () => true, true)
}
export function collapseAll () {
state = syncState(doc, state, [], () => false, true)
}
export function get() {
return doc
}
@ -227,10 +240,16 @@
* Toggle expanded state of a node
* @param {Path} path
* @param {boolean} expanded
* @param {boolean} [recursive=false]
*/
function handleExpand (path, expanded) {
console.log('handleExpand', path, expanded)
state = setIn(state, path.concat(STATE_EXPANDED), expanded)
function handleExpand (path, expanded, recursive = false) {
if (recursive) {
state = updateIn(state, path, (childState) => {
return syncState(getIn(doc, path), childState, [], () => expanded, true)
})
} else {
state = setIn(state, path.concat(STATE_EXPANDED), expanded)
}
}
/**

View File

@ -82,8 +82,9 @@
})
}
function toggle () {
onExpand(path, !expanded)
function toggleExpand (event) {
const recursive = event.ctrlKey
onExpand(path, !expanded, recursive)
}
function updateKey () {
@ -182,7 +183,7 @@
<div class='json-node'>
{#if type === 'array'}
<div class='header'>
<button class='expand' on:click={toggle}>
<button class='expand' on:click={toggleExpand}>
{#if expanded}
<Icon data={faCaretDown} />
{:else}
@ -235,7 +236,7 @@
{/if}
{:else if type === 'object'}
<div class='header'>
<button class='expand' on:click={toggle}>
<button class='expand' on:click={toggleExpand}>
{#if expanded}
<Icon data={faCaretDown} />
{:else}

View File

@ -12,9 +12,10 @@ import { updateProps } from './updateProps.js'
* @param {JSON | undefined} state
* @param {Path} path
* @param {function (path: Path) : boolean} expand
* @param {boolean} [forceRefresh=false] if true, force refreshing the expanded state
* @returns {JSON | undefined}
*/
export function syncState (document, state = undefined, path, expand) {
export function syncState (document, state = undefined, path, expand, forceRefresh = false) {
// TODO: this function can be made way more efficient if we pass prevState:
// when immutable, we can simply be done already when the state === prevState
@ -22,7 +23,8 @@ export function syncState (document, state = undefined, path, expand) {
const updatedState = {}
updatedState[STATE_PROPS] = updateProps(document, state && state[STATE_PROPS])
updatedState[STATE_EXPANDED] = state
updatedState[STATE_EXPANDED] = (state && !forceRefresh)
? state[STATE_EXPANDED]
: expand(path)
@ -31,7 +33,7 @@ export function syncState (document, state = undefined, path, expand) {
const childDocument = document[key]
if (isObjectOrArray(childDocument)) {
const childState = state && state[key]
updatedState[key] = syncState(childDocument, childState, path.concat(key), expand)
updatedState[key] = syncState(childDocument, childState, path.concat(key), expand, forceRefresh)
}
})
}
@ -42,13 +44,11 @@ export function syncState (document, state = undefined, path, expand) {
if (Array.isArray(document)) {
const updatedState = []
// TODO: can we make the state for array a regular object { limit: 100, items: [...] }?
updatedState[STATE_LIMIT] = state
? state[STATE_LIMIT]
: DEFAULT_LIMIT
updatedState[STATE_EXPANDED] = state
updatedState[STATE_EXPANDED] = (state && !forceRefresh)
? state[STATE_EXPANDED]
: expand(path)
@ -57,7 +57,7 @@ export function syncState (document, state = undefined, path, expand) {
const childDocument = document[i]
if (isObjectOrArray(childDocument)) {
const childState = state && state[i]
updatedState[i] = syncState(childDocument, childState, path.concat(i), expand)
updatedState[i] = syncState(childDocument, childState, path.concat(i), expand, forceRefresh)
}
}
}