Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control the expansion of individual nodes #59

Open
TomsBicans opened this issue Sep 4, 2024 · 4 comments
Open

Control the expansion of individual nodes #59

TomsBicans opened this issue Sep 4, 2024 · 4 comments

Comments

@TomsBicans
Copy link

TomsBicans commented Sep 4, 2024

Hello. I found this library for json data display, but i do not see a way how to calculate the initial expansion and collapse state of each individual node. Ideally, there could be a function that can be implemented and passed to the JsonView component called:

      shouldExpandNodeInitially={(
        keyPath: (string | number)[],      // denotes the keypath of the current node in the json structure
      ): boolean => {}

if the result is true - node should be expanded
if the result is false - node should be collapsed

This way the initial expansion could be calculated for each node separately and it would be possible to decide for each node if it should be opened or not. The current attribute 'collapsed' lets me control the collapsion state of the whole tree, which does not seem to allow to configure each node separately and limits my needs.

Any idea on how this issue could be solved?

@TomsBicans
Copy link
Author

TomsBicans commented Sep 4, 2024

To help understand the problem, here is the current code i am trying to implement:

        <JsonView
          id={rootNode}
          key={treeKey}
          value={tranformedTree}
          style={customTheme}
          keyName={rootNode}
          // collapsed={
          //   searchQuery || selectedDatapoints.length > 0 ? false : true
          // }
          collapsed={true}
          enableClipboard={false}
          displayObjectSize={false}
          displayDataTypes={false}
          onExpand={({ expand, value, keyid, keyName }) => {
            console.log('expand', expand, value, keyid, keyName);
          }}
        >
          <JsonView.Colon render={() => <></>} />
          <JsonView.Quote render={() => <></>} />
          <JsonView.BraceLeft render={() => <></>} />
          <JsonView.BraceRight render={() => <></>} />
          <JsonView.Ellipsis render={() => <></>} />
          <JsonView.KeyName
            render={(
              { children, ...props },
              { keyName, value, keys, parentValue },
            ) => {
              // Define whether the current node is a leaf node
              const isLeafNode = isValueALeafNode(value);

              // if (!keys) {
              //   return children;
              // }
              // const reversedKeys = [...keys].reverse();

              // console.log('reversedKeys', reversedKeys);
              // console.log('precomputedPaths', precomputedPaths);

              // const shouldBeExpanded = precomputedPaths.some(
              //   (precomputedPath) =>
              //     reversedKeys.every(
              //       (key, index) =>
              //         precomputedPath[
              //           precomputedPath.length - reversedKeys.length + index
              //         ] === key,
              //     ),
              // );

              // props['data-expanded'] = shouldBeExpanded;

              // Console log every incoming parameter
              // console.log('children', children);
              // console.log('props', props);
              // console.log('keyName', keyName);
              // console.log('keys', keys);
              // console.log('value', value);
              // console.log('parentValue', parentValue);
              // console.log('');

              if (!isLeafNode || !keyName || !keys) {
                return children;
              }

              const selection = keypathToMPIDDPID(
                [...(keys || [])].reverse(),
                tranformedTree,
              );

              if (!selection) {
                return children;
              }

              const assets = findAssetMemberAndMeasuredValue(
                monitoringSiteDetails,
                selection,
              );
              const isSelected = isDatapointSelected(selection);
              const isAllowedToSelectForThisDatapoint = isAllowedToSelect(
                selection,
                selectedDatapoints,
              );

              const displayValue = `${keyName as string} (${
                assets.measuredValue?.uomCode || '1'
              })`;

              return (
                <span
                  onClick={() =>
                    isAllowedToSelectForThisDatapoint &&
                    handleValueClick(selection.dpid, selection.mpid)
                  }
                  style={{
                    cursor: isAllowedToSelectForThisDatapoint
                      ? 'pointer'
                      : 'not-allowed',
                    color: isSelected
                      ? 'var(--sdx-color-int-blue)'
                      : isAllowedToSelectForThisDatapoint
                        ? 'var(--sdx-color-int-blue)'
                        : 'gray',
                    fontWeight: isSelected ? 'bold' : 'normal',
                  }}
                >
                  {highlightMatch(displayValue, searchQuery || '')}
                </span>
              );
            }}
          />
          <JsonView.Arrow
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            render={(props: any) => {
              const isExpanded = props['data-expanded'];
              return (
                <img
                  style={{
                    cursor: 'pointer',
                    width: '0.7rem',
                    marginRight: 10,
                    rotate: isExpanded ? '0deg' : '270deg',
                  }}
                  src="/icons/forms_selector.svg"
                />
              );
            }}
          />
          <JsonView.ValueQuote render={() => <></>} />
        </JsonView>

If it would be possible to implement such function and pass it to the JsonView component, then it would be great. Here is an example implementation:

shouldExpandNodeInitially={( // called for each node
            keyPath: (string | number)[],
          // data: unknown,
          // level: number,
        ) => {
          if (searchQuery) {
            return true;
          }
          console.log('keyPath', keyPath); //
          console.log('precomputedPaths', precomputedPaths); //<- keypaths to currently selected elements
          const res = precomputedPaths.some((precomputedPath) =>
            precomputedPath
              .slice(0, keyPath.length)
              .every((key, index) => key === keyPath[index]),
          );
          return res; // boolean result
        }}

@jaywcjlove
Copy link
Member

@TomsBicans My understanding is that you might need an onExpand event?

onExpand?: (props: { expand: boolean; value?: T; keyid: string; keyName?: string | number }) => void;

@TomsBicans
Copy link
Author

TomsBicans commented Sep 12, 2024

Hello. It is not exactly what i mean. The onExpand event is triggered through user interaction, which is not exactly what i am talking about. I can try to describe the problem i am facing.

I have a problem, that i need to open up the json tree in a specific way for the initial state - some nodes of the json tree should be opened, some nodes should be closed. Currently i see no way on how to control this mechanism without user interaction.

Another library i found has this kind of function i am talking about, but it lacks in other areas unrelated to the node expansion - it lets the developer implement the ShouldExpandNodeInitially function and the function is called automatically on the initial render for each node, so it is kind of easy to control the initial open/closed state for each individual node of the json tree. Have a look here: https://github.com/reduxjs/redux-devtools/blob/3c39eb49f2e5cb5ee18dcf8bc0cb9d66ec75573b/packages/react-json-tree/src/types.ts#L29

Maybe something like this can be implemented also in this project.

Thank you for your time.

jaywcjlove added a commit that referenced this issue Oct 16, 2024
jaywcjlove added a commit that referenced this issue Oct 16, 2024
@jaywcjlove
Copy link
Member

@TomsBicans upgrade v2.0.0-alpha.29

<JsonView
value={object}
collapsed={2}
shouldExpandNodeInitially={(isExpanded, { value, keys, level }) => {
if (keys.length > 0 && keys[0] == "object") {
return true
}
return isExpanded
}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants