Skip to content

Commit ba6c07c

Browse files
Merge pull request #5 from oslabs-beta/click-tab/ragad
Rendering nested structure functioning
2 parents 72fa443 + 161bd5f commit ba6c07c

File tree

5 files changed

+430
-8
lines changed

5 files changed

+430
-8
lines changed

src/app/FrontendTypes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ export interface ActionContainerProps {
108108
actionView: boolean;
109109
setActionView: React.Dispatch<React.SetStateAction<boolean>>;
110110
toggleActionContainer: () => void;
111+
snapshots: any
112+
currLocation: any
113+
}
114+
115+
export interface ProvConContainerProps {
116+
currentSnapshot: any;
111117
}
112118

113119
export interface StateContainerProps {

src/app/containers/ActionContainer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ function ActionContainer(props: ActionContainerProps): JSX.Element {
2626
const {
2727
toggleActionContainer, // function that handles Time Jump Sidebar view from MainContainer
2828
actionView, // local state declared in MainContainer
29-
setActionView, // function to update actionView state declared in MainContainer
29+
setActionView, // function to update actionView state declared in MainContainer,
30+
snapshots,
3031
} = props;
3132
const [recordingActions, setRecordingActions] = useState(true); // We create a local state 'recordingActions' and set it to true
3233
let actionsArr: JSX.Element[] = []; // we create an array 'actionsArr' that will hold elements we create later on
@@ -222,7 +223,8 @@ function ActionContainer(props: ActionContainerProps): JSX.Element {
222223
</Button>
223224
</div>
224225
<div className='snapshots'>
225-
{dropdownSelection === 'Provider/Consumer' && <ProvConContainer />}
226+
{dropdownSelection === 'Provider/Consumer' && <ProvConContainer currentSnapshot={currLocation.stateSnapshot}
227+
/>}
226228
{dropdownSelection === 'TimeJump' &&
227229
Object.keys(routes).map((route, i) => (
228230
<RouteDescription key={`route${i}`} actions={routes[route]} />

src/app/containers/MainContainer.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ function MainContainer(): JSX.Element {
212212
actionView={actionView}
213213
setActionView={setActionView}
214214
toggleActionContainer={toggleActionContainer}
215+
snapshots={snapshots}
216+
currLocation={currLocation}
215217
/>
216218
{/* @ts-ignore */}
217219
{snapshots.length ? (
Lines changed: 161 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,166 @@
1-
import React from "react";
1+
import { width } from '@mui/system';
2+
import React, {useState} from 'react';
3+
import { ProvConContainerProps} from '../FrontendTypes';
4+
5+
6+
const ProvConContainer = (props: ProvConContainerProps): JSX.Element => {
7+
8+
const { currentSnapshot } = props;
9+
10+
const keepContextAndProviderNodes = (node) => {
11+
if (!node) return null;
12+
13+
// Check if this node should be kept
14+
const hasContext =
15+
node?.componentData?.context && Object.keys(node.componentData.context).length > 0;
16+
const isProvider = node?.name && node.name.endsWith('Provider');
17+
const shouldKeepNode = hasContext || isProvider;
18+
19+
// Process children first
20+
let processedChildren = [];
21+
if (node.children) {
22+
processedChildren = node.children
23+
.map((child) => keepContextAndProviderNodes(child))
24+
.filter(Boolean); // Remove null results
25+
}
26+
27+
// If this node should be kept or has kept children, return it
28+
if (shouldKeepNode || processedChildren.length > 0) {
29+
return {
30+
...node,
31+
children: processedChildren,
32+
};
33+
}
34+
35+
// If neither the node should be kept nor it has kept children, filter it out
36+
return null;
37+
};
38+
const contextProvidersOnly = keepContextAndProviderNodes(currentSnapshot);
39+
console.log('context only', contextProvidersOnly)
40+
41+
42+
43+
// State for managing expansion of nodes
44+
const [expandedNodes, setExpandedNodes] = useState({});
45+
46+
// Toggle function to expand/collapse a node
47+
const toggleExpand = (nodeName) => {
48+
setExpandedNodes((prev) => ({
49+
...prev,
50+
[nodeName]: !prev[nodeName],
51+
}));
52+
};
53+
54+
// // Recursive function to render nested objects
55+
// const renderNestedObject = (node, depth = 0) => {
56+
// const isExpanded = expandedNodes[node.name];
57+
58+
// return (
59+
// <div key={node.name} style={{ marginLeft: `${depth * 20}px` }}>
60+
// <p
61+
// onClick={() => toggleExpand(node.name)}
62+
// style={{
63+
// cursor: "pointer",
64+
// fontWeight: "bold",
65+
// textDecoration: "underline",
66+
// color: isExpanded ? "green" : "blue",
67+
// }}
68+
// >
69+
// {node.name}
70+
// </p>
71+
72+
// {isExpanded &&
73+
// node?.children?.[0]?.componentData?.context &&
74+
// node?.children?.[0]?.componentData?.props?.value && (
75+
// <div>
76+
// <p>
77+
// Context Property:{" "}
78+
// {JSON.stringify(
79+
// node.children[0].componentData.context
80+
// )}
81+
// </p>
82+
// <p>
83+
// Context Value:{" "}
84+
// {JSON.stringify(
85+
// node.children[0].componentData.props.value
86+
// )}
87+
// </p>
88+
// </div>
89+
// )}
90+
91+
// {/* Recursively render children */}
92+
// {isExpanded &&
93+
// node.children &&
94+
// node.children.map((child) =>
95+
// renderNestedObject(child, depth + 1)
96+
// )}
97+
// </div>
98+
// );
99+
// };
100+
const style = {
101+
whiteSpace: "normal", // Allow text to wrap
102+
overflowWrap: "break-word", // Break long words
103+
width: "300px", // Limit container width
104+
border: "1px solid black", // Optional: Visualize container
105+
padding: "10px", // Optional: Add padding
106+
};
107+
108+
109+
const renderNestedObject = (node, depth = 0) => {
110+
const isExpanded = expandedNodes[node.name];
111+
112+
return (
113+
<div key={node.name}>
114+
{/* Render Node Name */}
115+
<p
116+
onClick={() => toggleExpand(node.name)}
117+
style={{
118+
cursor: "pointer",
119+
fontWeight: "bold",
120+
textDecoration: "underline",
121+
color: isExpanded ? "green" : "blue",
122+
}}
123+
>
124+
{node.name}
125+
</p>
126+
127+
{/* Render HookState if it exists */}
128+
{isExpanded && node.componentData?.hooksState && (
129+
<p style={{ whiteSpace: "normal" , overflowWrap: "break-word", padding: "20px"}}>
130+
State: {JSON.stringify(node.componentData.hooksState)}
131+
</p>
132+
)}
133+
134+
{/* Render Context Property if it exists */}
135+
{isExpanded && node.componentData?.context && Object.keys(node.componentData?.context).length !== 0 && (
136+
<p style={{ whiteSpace: "normal", overflowWrap: "break-word", padding: "20px"}}>
137+
Context Property: {JSON.stringify(node.componentData.context)}
138+
</p>
139+
)}
140+
141+
{/* Render Context Value if it exists */}
142+
{isExpanded && node.componentData?.props?.value && (
143+
<p style={{ whiteSpace: "normal" , overflowWrap: "break-word", padding: "10px"}}>
144+
Context Value: {JSON.stringify(node.componentData.props.value)}
145+
</p>
146+
)}
147+
148+
{/* Recursively Render Children */}
149+
{isExpanded &&
150+
node.children &&
151+
node.children.map((child) => renderNestedObject(child, depth + 1))}
152+
</div>
153+
);
154+
};
155+
2156

3-
const ProvConContainer = (): JSX.Element => {
4157
return (
5-
<div>
6-
hello
158+
<div style={{ width: "300px" }}>
159+
{renderNestedObject(contextProvidersOnly)}
7160
</div>
8-
)
9-
}
161+
);
162+
163+
};
164+
10165

11166
export default ProvConContainer;

0 commit comments

Comments
 (0)