From 5d84af035b8981cf51f1b4d7e66b5d90621f5692 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Tue, 5 Nov 2024 10:50:52 +0100 Subject: [PATCH] fix: only expand JSON after sort, transform and expand when isn't expanded already --- .../components/modes/treemode/TreeMode.svelte | 11 +++--- src/lib/logic/documentState.test.ts | 39 ++++++++++++++++++- src/lib/logic/documentState.ts | 19 ++++++--- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/lib/components/modes/treemode/TreeMode.svelte b/src/lib/components/modes/treemode/TreeMode.svelte index ba3d5c2c..fe9f6799 100644 --- a/src/lib/components/modes/treemode/TreeMode.svelte +++ b/src/lib/components/modes/treemode/TreeMode.svelte @@ -33,6 +33,7 @@ expandSection, expandSelf, expandSmart, + expandSmartIfCollapsed, getEnforceString, setInDocumentState, syncDocumentState @@ -813,7 +814,7 @@ // expand extracted object/array const path: JSONPath = [] return { - state: expandSmart(patchedJson, patchedState, path) + state: expandSmartIfCollapsed(patchedJson, patchedState, path) } } @@ -1042,8 +1043,8 @@ debug('onSort', rootPath, operations) handlePatch(operations, (patchedJson, patchedState) => ({ - // expand the newly replaced array and select it - state: expandSmart(patchedJson, patchedState, rootPath), + // expand the newly replaced array if needed, and select it + state: expandSmartIfCollapsed(patchedJson, patchedState, rootPath), selection: createValueSelection(rootPath) })) }, @@ -1096,8 +1097,8 @@ debug('onTransform', rootPath, operations) handlePatch(operations, (patchedJson, patchedState) => ({ - // expand the newly replaced array and select it - state: expandSmart(patchedJson, patchedState, rootPath), + // expand the newly replaced array if needed and select it + state: expandSmartIfCollapsed(patchedJson, patchedState, rootPath), selection: createValueSelection(rootPath) })) } diff --git a/src/lib/logic/documentState.test.ts b/src/lib/logic/documentState.test.ts index 0607bd56..63a01f68 100644 --- a/src/lib/logic/documentState.test.ts +++ b/src/lib/logic/documentState.test.ts @@ -18,6 +18,7 @@ import { expandSection, expandSelf, expandSmart, + expandSmartIfCollapsed, forEachVisibleIndex, getEnforceString, getInRecursiveState, @@ -38,7 +39,14 @@ import { type ValueDocumentState, type VisibleSection } from '$lib/types.js' -import { deleteIn, getIn, type JSONPatchDocument, setIn, updateIn } from 'immutable-json-patch' +import { + deleteIn, + getIn, + type JSONPatchDocument, + type JSONPath, + setIn, + updateIn +} from 'immutable-json-patch' import { isArrayRecursiveState } from 'svelte-jsoneditor' const json3 = [{ id: 0 }, { id: 1 }, { id: 2 }] @@ -1939,6 +1947,35 @@ describe('documentState', () => { expect(deleteInDocumentState(json, documentState, ['foo'])).toEqual(documentState) }) }) + + describe('expandSmartIfCollapsed', () => { + test('should only trigger expandSmart when the state is collapsed', () => { + const json = { nested: {} } + const stateCollapsed = createDocumentState({ json, expand: () => false }) + const stateExpanded = createDocumentState({ json, expand: (path) => path.length === 0 }) + const path: JSONPath = [] + + // will trigger smart expand, expanding all + expect(expandSmartIfCollapsed(json, stateCollapsed, path)).toEqual({ + expanded: true, + properties: { + nested: { + expanded: true, + properties: {}, + type: 'object' + } + }, + type: 'object' + }) + + // will not trigger smart expand, leaving the nested object collapsed as it was + expect(expandSmartIfCollapsed(json, stateExpanded, path)).toEqual({ + expanded: true, + properties: {}, + type: 'object' + }) + }) + }) }) /** diff --git a/src/lib/logic/documentState.ts b/src/lib/logic/documentState.ts index e93451dd..1f379506 100644 --- a/src/lib/logic/documentState.ts +++ b/src/lib/logic/documentState.ts @@ -82,16 +82,12 @@ export function createDocumentState({ json, expand }: CreateDocumentStateProps): DocumentState | undefined { - let documentState: DocumentState | undefined = createRecursiveState({ + const documentState: DocumentState | undefined = createRecursiveState({ json, factory: documentStateFactory }) as DocumentState - if (expand && documentState) { - documentState = expandPath(json, documentState, [], expand) - } - - return documentState + return expand && documentState ? expandPath(json, documentState, [], expand) : documentState } export function createArrayDocumentState({ expanded } = { expanded: false }): ArrayDocumentState { @@ -879,6 +875,17 @@ export function expandSmart( return expandPath(json, documentState, path, callback) } +export function expandSmartIfCollapsed( + json: unknown | undefined, + documentState: DocumentState | undefined, + path: JSONPath +) { + const nestedState = getInRecursiveState(json, documentState, path) + const isExpanded = isExpandableState(nestedState) ? nestedState.expanded : false + + return isExpanded ? documentState : expandSmart(json, documentState, path) +} + /** * Expand the root array or object, and in case of an array, expand the first array item */