mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-12 19:02:53 +08:00
prevent expand btn expanding all
This commit is contained in:
parent
263696ed88
commit
41638eb35b
1
TODO.md
1
TODO.md
@ -5,7 +5,6 @@
|
||||
|
||||
## Enhancements:
|
||||
|
||||
- [ ] Prevent expand button expanding all nodes, should expand only target node
|
||||
- [ ] Clear rewrite of [parsing algorithm](/src/utils/jsonParser.ts)
|
||||
- [ ] Performance Optimization
|
||||
- [ ] Fix `useInViewport` hook for performance
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { MdCompareArrows } from "react-icons/md";
|
||||
import { MdLink, MdLinkOff } from "react-icons/md";
|
||||
import { useInViewport } from "react-in-viewport";
|
||||
import { CustomNodeProps } from "src/components/CustomNode";
|
||||
import useConfig from "src/hooks/store/useConfig";
|
||||
@ -57,13 +57,15 @@ const TextNode: React.FC<TextNodeProps> = ({
|
||||
const hideCollapse = useStored((state) => state.hideCollapse);
|
||||
const expandNodes = useGraph((state) => state.expandNodes);
|
||||
const collapseNodes = useGraph((state) => state.collapseNodes);
|
||||
const [isExpanded, setIsExpanded] = React.useState(true);
|
||||
const isExpanded = useGraph((state) =>
|
||||
state.collapsedParents.includes(node.id)
|
||||
);
|
||||
|
||||
const handleExpand = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
setIsExpanded(!isExpanded);
|
||||
// setIsExpanded(!isExpanded);
|
||||
|
||||
if (isExpanded) collapseNodes(node.id);
|
||||
if (!isExpanded) collapseNodes(node.id);
|
||||
else expandNodes(node.id);
|
||||
};
|
||||
|
||||
@ -94,7 +96,11 @@ const TextNode: React.FC<TextNodeProps> = ({
|
||||
|
||||
{inViewport && isParent && hasCollapse && !hideCollapse && (
|
||||
<StyledExpand onClick={handleExpand}>
|
||||
<MdCompareArrows size={18} />
|
||||
{isExpanded ? (
|
||||
<MdLinkOff size={18} />
|
||||
) : (
|
||||
<MdLink size={18} />
|
||||
)}
|
||||
</StyledExpand>
|
||||
)}
|
||||
</StyledTextNodeWrapper>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { Node, NodeProps } from "reaflow";
|
||||
import useGraph from "src/hooks/store/useGraph";
|
||||
import ObjectNode from "./ObjectNode";
|
||||
import TextNode from "./TextNode";
|
||||
|
||||
|
@ -7,6 +7,7 @@ export interface Graph {
|
||||
edges: EdgeData[];
|
||||
collapsedNodes: string[];
|
||||
collapsedEdges: string[];
|
||||
collapsedParents: string[];
|
||||
}
|
||||
|
||||
interface GraphActions {
|
||||
@ -20,6 +21,7 @@ const initialStates: Graph = {
|
||||
edges: [],
|
||||
collapsedNodes: [],
|
||||
collapsedEdges: [],
|
||||
collapsedParents: [],
|
||||
};
|
||||
|
||||
const useGraph = create<Graph & GraphActions>((set, get) => ({
|
||||
@ -31,29 +33,36 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
|
||||
[key]: value,
|
||||
}),
|
||||
expandNodes: (nodeId) => {
|
||||
const childrenNodes = getOutgoers(nodeId, get().nodes, get().edges);
|
||||
const [childrenNodes, matchingNodes] = getOutgoers(
|
||||
nodeId,
|
||||
get().nodes,
|
||||
get().edges,
|
||||
get().collapsedParents
|
||||
);
|
||||
const childrenEdges = getChildrenEdges(childrenNodes, get().edges);
|
||||
|
||||
const nodeIds = childrenNodes.map((node) => node.id);
|
||||
const nodeIds = childrenNodes.map((node) => node.id).concat(matchingNodes);
|
||||
const edgeIds = childrenEdges.map((edge) => edge.id);
|
||||
|
||||
const collapsedParents = get().collapsedParents.filter((cp) => cp !== nodeId);
|
||||
const collapsedNodes = get().collapsedNodes.filter((nodeId) => !nodeIds.includes(nodeId));
|
||||
const collapsedEdges = get().collapsedEdges.filter((edgeId) => !edgeIds.includes(edgeId));
|
||||
|
||||
set({
|
||||
collapsedNodes: get().collapsedNodes.filter(
|
||||
(nodeId) => !nodeIds.includes(nodeId)
|
||||
),
|
||||
collapsedEdges: get().collapsedEdges.filter(
|
||||
(edgeId) => !edgeIds.includes(edgeId)
|
||||
),
|
||||
collapsedParents,
|
||||
collapsedNodes,
|
||||
collapsedEdges,
|
||||
});
|
||||
},
|
||||
collapseNodes: (nodeId) => {
|
||||
const childrenNodes = getOutgoers(nodeId, get().nodes, get().edges);
|
||||
const [childrenNodes] = getOutgoers(nodeId, get().nodes, get().edges);
|
||||
const childrenEdges = getChildrenEdges(childrenNodes, get().edges);
|
||||
|
||||
const nodeIds = childrenNodes.map((node) => node.id);
|
||||
const edgeIds = childrenEdges.map((edge) => edge.id);
|
||||
|
||||
set({
|
||||
collapsedParents: get().collapsedParents.concat(nodeId),
|
||||
collapsedNodes: get().collapsedNodes.concat(nodeIds),
|
||||
collapsedEdges: get().collapsedEdges.concat(edgeIds),
|
||||
});
|
||||
|
@ -1,18 +1,23 @@
|
||||
export const getOutgoers = (
|
||||
nodeId: string,
|
||||
nodes: NodeData[],
|
||||
edges: EdgeData[]
|
||||
): NodeData[] => {
|
||||
const allOutgoers: NodeData[] = [];
|
||||
edges: EdgeData[],
|
||||
parent: string[] = []
|
||||
): [NodeData[], string[]] => {
|
||||
const outgoerNodes: NodeData[] = [];
|
||||
const matchingNodes: string[] = [];
|
||||
|
||||
const runner = (nodeId: string) => {
|
||||
const outgoerIds = edges.filter((e) => e.from === nodeId).map((e) => e.to);
|
||||
const nodeList = nodes.filter((n) => outgoerIds.includes(n.id));
|
||||
allOutgoers.push(...nodeList);
|
||||
const nodeList = nodes.filter((n) => {
|
||||
if (parent.includes(n.id) && !matchingNodes.includes(n.id)) matchingNodes.push(n.id);
|
||||
return outgoerIds.includes(n.id) && !parent.includes(n.id);
|
||||
});
|
||||
|
||||
outgoerNodes.push(...nodeList);
|
||||
nodeList.forEach((node) => runner(node.id));
|
||||
};
|
||||
|
||||
runner(nodeId);
|
||||
|
||||
return allOutgoers;
|
||||
return [outgoerNodes, matchingNodes];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user