Limit nodes opened by default in the JSON Tree component (#11002)

- Add a parameter to choose which nodes to open by default
- On the Admin Panel, open all nodes by default
- On the Workflow Run step output, open only the two first depths
- On the Workflow Run step input, open only the previous step first
depth
- Display `[empty string]` when a node is an empty string
- Now, display `null` instead of `[null]`

## Demo


https://github.com/user-attachments/assets/99b3078a-da3c-4330-b0ff-ddb2e360d933

Closes https://github.com/twentyhq/core-team-issues/issues/538
This commit is contained in:
Baptiste Devessier
2025-03-19 11:44:34 +01:00
committed by GitHub
parent 15a2cb5141
commit 1ecc5e2bf6
13 changed files with 141 additions and 11 deletions

View File

@ -5,6 +5,7 @@ import { JsonArrow } from '@ui/json-visualizer/components/internal/JsonArrow';
import { JsonList } from '@ui/json-visualizer/components/internal/JsonList';
import { JsonNodeLabel } from '@ui/json-visualizer/components/internal/JsonNodeLabel';
import { JsonNode } from '@ui/json-visualizer/components/JsonNode';
import { useJsonTreeContextOrThrow } from '@ui/json-visualizer/hooks/useJsonTreeContextOrThrow';
import { ANIMATION } from '@ui/theme';
import { AnimatePresence, motion } from 'framer-motion';
import { useState } from 'react';
@ -49,9 +50,13 @@ export const JsonNestedNode = ({
depth: number;
keyPath: string;
}) => {
const { shouldExpandNodeInitially } = useJsonTreeContextOrThrow();
const hideRoot = !isDefined(label);
const [isOpen, setIsOpen] = useState(true);
const [isOpen, setIsOpen] = useState(
shouldExpandNodeInitially({ keyPath, depth }),
);
const renderedChildren = (
<StyledJsonList

View File

@ -1,4 +1,10 @@
import { isBoolean, isNull, isNumber, isString } from '@sniptt/guards';
import {
isBoolean,
isNonEmptyString,
isNull,
isNumber,
isString,
} from '@sniptt/guards';
import {
IconCheckbox,
IconCircleOff,
@ -23,7 +29,7 @@ export const JsonNode = ({
depth: number;
keyPath: string;
}) => {
const { shouldHighlightNode } = useJsonTreeContextOrThrow();
const { shouldHighlightNode, emptyStringLabel } = useJsonTreeContextOrThrow();
const isHighlighted = shouldHighlightNode?.(keyPath) ?? false;
@ -31,7 +37,7 @@ export const JsonNode = ({
return (
<JsonValueNode
label={label}
valueAsString="[null]"
valueAsString="null"
Icon={IconCircleOff}
isHighlighted={isHighlighted}
/>
@ -42,7 +48,7 @@ export const JsonNode = ({
return (
<JsonValueNode
label={label}
valueAsString={value}
valueAsString={isNonEmptyString(value) ? value : emptyStringLabel}
Icon={IconTypography}
isHighlighted={isHighlighted}
/>

View File

@ -1,20 +1,27 @@
import { JsonList } from '@ui/json-visualizer/components/internal/JsonList';
import { JsonNode } from '@ui/json-visualizer/components/JsonNode';
import { JsonTreeContextProvider } from '@ui/json-visualizer/components/JsonTreeContextProvider';
import { ShouldExpandNodeInitiallyProps } from '@ui/json-visualizer/contexts/JsonTreeContext';
import { JsonValue } from 'type-fest';
export const JsonTree = ({
value,
shouldHighlightNode,
shouldExpandNodeInitially,
emptyArrayLabel,
emptyObjectLabel,
emptyStringLabel,
arrowButtonCollapsedLabel,
arrowButtonExpandedLabel,
}: {
value: JsonValue;
shouldHighlightNode?: (keyPath: string) => boolean;
shouldExpandNodeInitially: (
params: ShouldExpandNodeInitiallyProps,
) => boolean;
emptyArrayLabel: string;
emptyObjectLabel: string;
emptyStringLabel: string;
arrowButtonCollapsedLabel: string;
arrowButtonExpandedLabel: string;
}) => {
@ -22,8 +29,10 @@ export const JsonTree = ({
<JsonTreeContextProvider
value={{
shouldHighlightNode,
shouldExpandNodeInitially,
emptyArrayLabel,
emptyObjectLabel,
emptyStringLabel,
arrowButtonCollapsedLabel,
arrowButtonExpandedLabel,
}}