Expand array limit when search result is beyond the visible items

This commit is contained in:
josdejong 2020-05-31 10:54:34 +02:00
parent 34e45a04c4
commit e5ec845d4f
5 changed files with 52 additions and 16 deletions

View File

@ -1,17 +1,22 @@
<script> <script>
import { tick } from 'svelte' import { tick } from 'svelte'
import { EXPANDED_PROPERTY, SCROLL_DURATION } from './constants.js' import {
DEFAULT_LIMIT,
EXPANDED_PROPERTY,
LIMIT_PROPERTY,
SCROLL_DURATION
} from './constants.js'
import SearchBox from './SearchBox.svelte' import SearchBox from './SearchBox.svelte'
import Icon from 'svelte-awesome' import Icon from 'svelte-awesome'
import { faSearch, faUndo, faRedo } from '@fortawesome/free-solid-svg-icons' import { faSearch, faUndo, faRedo } from '@fortawesome/free-solid-svg-icons'
import { createHistory } from './history.js' import { createHistory } from './history.js'
import Node from './JSONNode.svelte' import Node from './JSONNode.svelte'
import { existsIn, setIn } from './utils/immutabilityHelpers.js' import { existsIn, getIn, setIn } from './utils/immutabilityHelpers.js'
import { compileJSONPointer } from './utils/jsonPointer.js' import { compileJSONPointer } from './utils/jsonPointer.js'
import { keyComboFromEvent } from './utils/keyBindings.js' import { keyComboFromEvent } from './utils/keyBindings.js'
import { flattenSearch, search } from './utils/search.js' import { flattenSearch, search } from './utils/search.js'
import { immutableJSONPatch } from './utils/immutableJSONPatch' import { immutableJSONPatch } from './utils/immutableJSONPatch'
import { isEqual } from 'lodash-es' import { isEqual, isNumber } from 'lodash-es'
import jump from './assets/jump.js/src/jump.js' import jump from './assets/jump.js/src/jump.js'
let divContents let divContents
@ -194,13 +199,33 @@
state = setIn(state, path.concat(EXPANDED_PROPERTY), expanded) state = setIn(state, path.concat(EXPANDED_PROPERTY), expanded)
} }
/**
* Change limit
* @param {Path} path
* @param {boolean} limit
*/
function handleLimit (path, limit) {
state = setIn(state, path.concat(LIMIT_PROPERTY), limit)
}
/** /**
* Expand all nodes on given path * Expand all nodes on given path
* @param {Path} path * @param {Path} path
*/ */
function expandPath (path) { function expandPath (path) {
for (let i = 1; i < path.length; i++) { for (let i = 1; i < path.length; i++) {
state = setIn(state, path.slice(0, i).concat(EXPANDED_PROPERTY), true) const partialPath = path.slice(0, i)
state = setIn(state, partialPath.concat(EXPANDED_PROPERTY), true)
// if needed, enlarge the limit such that the search result becomes visible
const key = path[i]
if (isNumber(key)) {
const limit = getIn(state, partialPath.concat(LIMIT_PROPERTY)) || DEFAULT_LIMIT
if (key > limit) {
const newLimit = Math.ceil(key / DEFAULT_LIMIT) * DEFAULT_LIMIT
state = setIn(state, partialPath.concat(LIMIT_PROPERTY), newLimit)
}
}
} }
} }
@ -299,6 +324,7 @@
onChangeKey={handleChangeKey} onChangeKey={handleChangeKey}
onPatch={handlePatch} onPatch={handlePatch}
onExpand={handleExpand} onExpand={handleExpand}
onLimit={handleLimit}
/> />
<div class='bottom'></div> <div class='bottom'></div>
</div> </div>

View File

@ -1,6 +1,7 @@
<script> <script>
import { import {
EXPANDED_PROPERTY, DEBOUNCE_DELAY, DEFAULT_LIMIT,
EXPANDED_PROPERTY, LIMIT_PROPERTY,
SEARCH_PROPERTY, SEARCH_PROPERTY,
SEARCH_VALUE SEARCH_VALUE
} from './constants.js' } from './constants.js'
@ -22,15 +23,13 @@
export let onPatch export let onPatch
export let onChangeKey export let onChangeKey
export let onExpand export let onExpand
export let onLimit
$: expanded = state && state[EXPANDED_PROPERTY] $: expanded = state && state[EXPANDED_PROPERTY]
$: limit = state && state[LIMIT_PROPERTY] || DEFAULT_LIMIT
const DEBOUNCE_DELAY = 300 // milliseconds TODO: make the debounce delay configurable?
const DEFAULT_LIMIT = 100
const escapeUnicode = false // TODO: pass via options const escapeUnicode = false // TODO: pass via options
let limit = DEFAULT_LIMIT
let domKey let domKey
let domValue let domValue
@ -208,7 +207,7 @@
} }
function handleShowAll () { function handleShowAll () {
limit = Infinity onLimit(path, Infinity)
} }
</script> </script>
@ -254,6 +253,7 @@
onChangeKey={handleChangeKey} onChangeKey={handleChangeKey}
onPatch={onPatch} onPatch={onPatch}
onExpand={onExpand} onExpand={onExpand}
onLimit={onLimit}
/> />
{/each} {/each}
{#if limited} {#if limited}
@ -307,6 +307,7 @@
onChangeKey={handleChangeKey} onChangeKey={handleChangeKey}
onPatch={onPatch} onPatch={onPatch}
onExpand={onExpand} onExpand={onExpand}
onLimit={onLimit}
/> />
{/each} {/each}
</div> </div>

View File

@ -2,10 +2,9 @@
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import Icon from 'svelte-awesome' import Icon from 'svelte-awesome'
import { faSearch, faChevronDown, faChevronUp, faTimes } from '@fortawesome/free-solid-svg-icons' import { faSearch, faChevronDown, faChevronUp, faTimes } from '@fortawesome/free-solid-svg-icons'
import { DEBOUNCE_DELAY } from './constants.js'
import { keyComboFromEvent } from './utils/keyBindings.js' import { keyComboFromEvent } from './utils/keyBindings.js'
const DEBOUNCE_DELAY = 300 // milliseconds TODO: make the debounce delay configurable?
export let text = '' export let text = ''
let inputText = '' let inputText = ''
export let resultCount = 0 export let resultCount = 0

View File

@ -1,6 +1,9 @@
export const EXPANDED_PROPERTY = '$jse:expanded' export const EXPANDED_PROPERTY = '$jse:expanded'
export const LIMIT_PROPERTY = '$jse:limit'
export const SEARCH_PROPERTY = '$jse:search:property' export const SEARCH_PROPERTY = '$jse:search:property'
export const SEARCH_VALUE = '$jse:search:value' export const SEARCH_VALUE = '$jse:search:value'
export const SCROLL_DURATION = 300 // ms export const SCROLL_DURATION = 300 // ms
export const DEBOUNCE_DELAY = 300
export const DEFAULT_LIMIT = 100

View File

@ -1,3 +1,4 @@
import { isNumber } from 'lodash-es'
import { SEARCH_PROPERTY, SEARCH_VALUE } from '../constants.js' import { SEARCH_PROPERTY, SEARCH_VALUE } from '../constants.js'
import { valueType } from './typeUtils.js' import { valueType } from './typeUtils.js'
@ -53,7 +54,7 @@ export function flattenSearch (searchResult) {
const type = valueType(value) const type = valueType(value)
if (type === 'array') { if (type === 'array') {
searchResult.forEach((item, index) => { value.forEach((item, index) => {
_flattenSearch(item, path.concat(index)) _flattenSearch(item, path.concat(index))
}) })
} else if (type === 'object') { } else if (type === 'object') {
@ -72,12 +73,18 @@ function createOrAdd(object, key, value) {
if (object) { if (object) {
object[key] = value object[key] = value
return object return object
} else {
if (isNumber(key)) {
const array = []
array[key] = value
return array
} else { } else {
return { return {
[key]: value [key]: value
} }
} }
} }
}
/** /**
* Do a case insensitive search for a search text in a text * Do a case insensitive search for a search text in a text