expand the active search result if not expanded
This commit is contained in:
parent
bef37648b7
commit
0e490fdeee
|
@ -1,13 +1,12 @@
|
|||
import { createElement as h, Component } from 'react'
|
||||
|
||||
import Ajv from 'ajv'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import { updateIn, getIn, setIn } from '../utils/immutabilityHelpers'
|
||||
import { parseJSON } from '../utils/jsonUtils'
|
||||
import { enrichSchemaError } from '../utils/schemaUtils'
|
||||
import {
|
||||
jsonToData, dataToJson, toDataPath, patchData, pathExists,
|
||||
expand, addErrors, addFocus,
|
||||
expand, expandPath, addErrors,
|
||||
search, addSearchResults, nextSearchResult, previousSearchResult
|
||||
} from '../jsonData'
|
||||
import {
|
||||
|
@ -317,13 +316,14 @@ export default class TreeMode extends Component {
|
|||
/** @private */
|
||||
handleSearch = (text) => {
|
||||
const searchResults = search(this.state.data, text)
|
||||
const active = searchResults[0] || null
|
||||
|
||||
this.setState(setIn(this.state, ['search'], {
|
||||
text,
|
||||
active: searchResults[0] || null
|
||||
}))
|
||||
this.setState({
|
||||
search: { text, active },
|
||||
data: expandPath(this.state.data,active && active.path)
|
||||
})
|
||||
|
||||
// TODO: focus on the active result
|
||||
// TODO: scroll to the active result
|
||||
}
|
||||
|
||||
/** @private */
|
||||
|
@ -332,9 +332,12 @@ export default class TreeMode extends Component {
|
|||
if (searchResults) {
|
||||
const next = nextSearchResult(searchResults, this.state.search.active)
|
||||
|
||||
this.setState(setIn(this.state, ['search', 'active'], next))
|
||||
this.setState({
|
||||
search: setIn(this.state.search, ['active'], next),
|
||||
data: expandPath(this.state.data, next && next.path)
|
||||
})
|
||||
|
||||
// TODO: focus on the active result
|
||||
// TODO: scroll to the active result
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,9 +347,12 @@ export default class TreeMode extends Component {
|
|||
if (searchResults) {
|
||||
const previous = previousSearchResult(searchResults, this.state.search.active)
|
||||
|
||||
this.setState(setIn(this.state, ['search', 'active'], previous))
|
||||
this.setState({
|
||||
search: setIn(this.state.search, ['active'], previous),
|
||||
data: expandPath(this.state.data, previous && previous.path)
|
||||
})
|
||||
|
||||
// TODO: focus on the active result
|
||||
// TODO: scroll to the active result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,7 @@ export default class Search extends Component {
|
|||
}
|
||||
|
||||
render () {
|
||||
// TODO: focus on search results
|
||||
// TODO: expand the focused search result if not expanded
|
||||
// TODO: scroll to active search result
|
||||
|
||||
return h('div', {className: 'jsoneditor-search'}, [
|
||||
this.renderResultsCount(this.props.resultsCount),
|
||||
|
|
|
@ -9,7 +9,7 @@ import { setIn, updateIn, getIn, deleteIn, insertAt } from './utils/immutability
|
|||
import { isObject } from './utils/typeUtils'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
|
||||
import type {JSONData, DataPointer} from './types'
|
||||
import type {JSONData, DataPointer, Path} from './types'
|
||||
|
||||
/**
|
||||
* Expand function which will expand all nodes
|
||||
|
@ -115,6 +115,17 @@ export function toDataPath (data, path) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a path of a JSON object into a path in the corresponding data model
|
||||
* @param {JSONData} data
|
||||
* @param {Path} path
|
||||
* @return {Path} dataPath
|
||||
* @private
|
||||
*/
|
||||
export function toPath (data, dataPath) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a patch to a JSONData object
|
||||
* @param {JSONData} data
|
||||
|
@ -458,10 +469,10 @@ export function test (data, path, value) {
|
|||
* When a path, the object/array at this path will be expanded/collapsed
|
||||
* When a function, all objects and arrays for which callback
|
||||
* returns true will be expanded/collapsed
|
||||
* @param {boolean} expanded New expanded state: true to expand, false to collapse
|
||||
* @param {boolean} [expanded=true] New expanded state: true to expand, false to collapse
|
||||
* @return {JSONData}
|
||||
*/
|
||||
export function expand (data, callback, expanded) {
|
||||
export function expand (data, callback, expanded: boolean = true) {
|
||||
// console.log('expand', callback, expand)
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
|
@ -485,6 +496,23 @@ export function expand (data, callback, expanded) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand all Objects and Arrays on a path
|
||||
*/
|
||||
export function expandPath (data: JSONData, path: Path) {
|
||||
let updatedData = data
|
||||
|
||||
if (path) {
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
const pathPart = path.slice(0, i + 1)
|
||||
// console.log('expandPath', path, i, pathPart)
|
||||
updatedData = expand(updatedData, pathPart, true)
|
||||
}
|
||||
}
|
||||
|
||||
return updatedData
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge one or multiple errors (for example JSON schema errors)
|
||||
* into the data
|
||||
|
@ -522,7 +550,7 @@ export function search (data: JSONData, text: string): DataPointer[] {
|
|||
const parentPath = allButLast(path)
|
||||
const parent = getIn(data, toDataPath(data, parentPath))
|
||||
if (parent.type === 'Object') {
|
||||
results.push({ dataPath: path, type: 'property' })
|
||||
results.push({ path, type: 'property' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -530,7 +558,7 @@ export function search (data: JSONData, text: string): DataPointer[] {
|
|||
// check value
|
||||
if (value.type === 'value') {
|
||||
if (containsCaseInsensitive(value.value, text)) {
|
||||
results.push({ dataPath: path, type: 'value' })
|
||||
results.push({ path, type: 'value' })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -594,13 +622,13 @@ export function addSearchResults (data: JSONData, searchResults: DataPointer[],
|
|||
|
||||
searchResults.forEach(function (searchResult) {
|
||||
if (searchResult.type === 'value') {
|
||||
const dataPath = toDataPath(data, searchResult.dataPath).concat('searchResult')
|
||||
const dataPath = toDataPath(data, searchResult.path).concat('searchResult')
|
||||
const value = isEqual(searchResult, activeSearchResult) ? 'active' : 'normal'
|
||||
updatedData = setIn(updatedData, dataPath, value)
|
||||
}
|
||||
|
||||
if (searchResult.type === 'property') {
|
||||
const valueDataPath = toDataPath(data, searchResult.dataPath)
|
||||
const valueDataPath = toDataPath(data, searchResult.path)
|
||||
const propertyDataPath = allButLast(valueDataPath).concat('searchResult')
|
||||
const value = isEqual(searchResult, activeSearchResult) ? 'active' : 'normal'
|
||||
updatedData = setIn(updatedData, propertyDataPath, value)
|
||||
|
@ -615,12 +643,12 @@ export function addSearchResults (data: JSONData, searchResults: DataPointer[],
|
|||
*/
|
||||
export function addFocus (data: JSONData, focusOn: DataPointer) {
|
||||
if (focusOn.type == 'value') {
|
||||
const dataPath = toDataPath(data, focusOn.dataPath).concat('focus')
|
||||
const dataPath = toDataPath(data, focusOn.path).concat('focus')
|
||||
return setIn(data, dataPath, true)
|
||||
}
|
||||
|
||||
if (focusOn.type === 'property') {
|
||||
const valueDataPath = toDataPath(data, focusOn.dataPath)
|
||||
const valueDataPath = toDataPath(data, focusOn.path)
|
||||
const propertyDataPath = allButLast(valueDataPath).concat('focus')
|
||||
return setIn(data, propertyDataPath, true)
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ export type JSONData = ObjectData | ArrayData | ValueData
|
|||
export type Path = string[]
|
||||
|
||||
export type DataPointer = {
|
||||
dataPath: Path,
|
||||
path: Path,
|
||||
type: DataPointerType
|
||||
}
|
||||
// TODO: DataPointer.dataPath is an array, JSONSchemaError.dataPath is a string -> make this consistent
|
||||
|
|
Loading…
Reference in New Issue