Repository: vishalpalaniappan/automated-system-viewer
Pull request #7: Load systems by querying ASP and provide interface for user to select a system.
Author: login: vishalpalaniappan
Created: 2025-04-24T06:15:19Z | Merged: 2025-04-25T05:40:28Z

This PR setups up the structure needed to load systems into ASV by communicating with ASP's query handler. 

## Changes Introduced
On a high level here are the changes made:

### Websocket Client
- Introduced a class to represent each system.
- When the websocket server connects, a message is sent to load all systems.
- When systems are received, they are used to create instances of the system class and are loaded into systems list. 
- SystemList is exposed to child components using a context.

### System Selector
- The systems list is loaded by the SystemSelector component.
- All unique system id's are found and the system drop down list is populated.
- Select the first system id by default.
- For the selected system id, get all the unique versions and populate the drop down list.
- Select the first version by default. 
- For the selected system id and version, get all the deployment ids.
- Select the first deployment id by default.
- When the any of the options are changed using dropdown, find the new values (ex. new list of versions of selected system).

### Trace View
- This PR also introduces a resizable side container which holds the system selector and trace view component.
- The trace view component is a skeleton that will be developed in the next PR.
- It will provide a list of traces for the selected system id, version and deployment id.

### Trace Diagram
- This PR introduces a trace diagram component.
- Currently the graph that is loaded is hardcoded.
- In a coming PR, it will load the flow graph for the selected trace.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a system selector interface with dropdowns for system, version, and deployment selection.
  - Added a trace visualization diagram displaying execution flows using an interactive flowchart.
  - Enabled vertical resizing between system selector and trace sections for improved layout control.

- **Refactor**
  - Simplified the file viewer to display only the trace diagram.
  - Updated context and provider structure to support systems list management.

- **Style**
  - Added new styles for the system selector, container, and draggable handle for a cohesive UI.

- **Chores**
  - Updated dependencies, adding libraries for graph layouts and flow diagrams, and removing unused packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/package.json b/package.json
index 2aa84e8..66e33ab 100644
--- a/package.json
+++ b/package.json
@@ -21,10 +21,11 @@
   },
   "homepage": "https://github.com/vishalpalaniappan/diagnostic-log-viewer#readme",
   "dependencies": {
+    "@dagrejs/dagre": "^1.1.4",
     "@monaco-editor/react": "^4.4.6",
+    "@xyflow/react": "^12.6.0",
     "bootstrap": "^5.2.3",
     "buffer": "^6.0.3",
-    "clp-ffi-js": "^0.3.3",
     "compression-webpack-plugin": "^10.0.0",
     "crypto-browserify": "^3.12.0",
     "css-unicode-loader": "^1.0.3",
@@ -39,7 +40,6 @@
     "react-bootstrap": "^2.5.0",
     "react-bootstrap-icons": "^1.11.3",
     "react-dom": "^18.2.0",
-    "react-grid-layout": "^1.5.0",
     "react-monaco-editor": "^0.50.1",
     "react-router-dom": "^6.4.3",
     "react-use-websocket": "^3.0.0",
diff --git a/src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js b/src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js
new file mode 100644
index 0000000..b59c652
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js
@@ -0,0 +1,127 @@
+import React, {useContext, useEffect, useState} from "react";
+
+import SystemsContext from "../../../Providers/SystemsContext";
+
+import "./SystemSelector.scss";
+
+/**
+ * Contains the system selector components.
+ * @return {JSX.Element}
+ */
+export function SystemSelector () {
+    const {systemsList} = useContext(SystemsContext);
+
+    const [systems, setSystems] = useState([]);
+    const [versions, setVersions] = useState([]);
+    const [deployments, setDeployments] = useState([]);
+    const [activeSystemId, setActiveSystemId] = useState();
+    const [activeVersion, setActiveVersion] = useState();
+    const [activeDeployment, setActiveDeployment] = useState();
+
+    // Load system select dropdown from systemsList and set active system.
+    const loadSystems = () => {
+        if (!systemsList || !Array.isArray(systemsList) || systemsList.length === 0) {
+            setSystems([]);
+            setVersions([]);
+            setDeployments([]);
+            return;
+        }
+        const sysIds = [...new Set(systemsList.map((item) => item.sysId))];
+        const _systems = [];
+        sysIds.forEach((id, index) => {
+            _systems.push(<option key={id} value={id}>{id}</option>);
+        });
+        setSystems(_systems);
+        if (sysIds.length > 0) {
+            loadVersions(sysIds[0]);
+        }
+    };
+
+    // Given a system ID, load versions into select dropdown, set active version
+    const loadVersions = (systemid) => {
+        setActiveSystemId(systemid);
+        const filteredSystems = systemsList.filter((obj) => {return obj.sysId === systemid;});
+        const versionsList = [...new Set(filteredSystems.map((item) => item.version))];
+        const _versions = [];
+        versionsList.forEach((version, index) => {
+            _versions.push(<option key={version} value={version}>{version}</option>);
+        });
+        setVersions(_versions);
+        loadDeployments(systemid, versionsList[0]);
+    };
+
+    // Given a system id and version load deployments and set active deployment.
+    const loadDeployments = (systemid, version) => {
+        setActiveVersion(version);
+        const system = systemsList.filter(
+            (obj) => {return (obj.sysId === systemid && obj.version == version);}
+        )[0];
+        const _deployments = [];
+        if (system && system.deployments && Array.isArray(system.deployments) && system.deployments.length > 0) {
+            system.deployments.forEach((deployment, index) => {
+                const id = deployment.deployment_id;
+                _deployments.push(<option key={id} value={id}>{id}</option>);
+            });
+            setDeployments(_deployments);
+            setActiveDeployment(system.deployments[0].deployment_id);
+        } else {
+            setDeployments([]);
+            setActiveDeployment(null);
+        }
+    };
+
+    // Callback functions when selector is manually changed
+    const selectVersion = (e) => {
+        loadDeployments(activeSystemId, e.target.value);
+    };
+
+    const selectSystemId = (e) => {
+        loadVersions(e.target.value);
+    };
+
+    const selectDeployment = (e) => {
+        setActiveDeployment(e.target.value);
+    };
+
+    // React to changes in systems, system and version
+    useEffect(() => {
+        if (systemsList) {
+            loadSystems();
+        }
+    }, [systemsList]);
+
+    return (
+        <div className="d-flex flex-column systemContainer">
+            <div className="d-flex flex-row systemSelectRow">
+                <div style={{width: "100px"}}>System ID:</div>
+                <div className="flex-grow-1">
+                    <select
+                        onChange={selectSystemId}
+                        className="customSelector">
+                        {systems}
+                    </select>
+                </div>
+            </div>
+            <div className="d-flex flex-row systemSelectRow">
+                <div style={{width: "100px"}}>Version:</div>
+                <div className="flex-grow-1">
+                    <select
+                        onChange={selectVersion}
+                        className="customSelector">
+                        {versions}
+                    </select>
+                </div>
+            </div>
+            <div className="d-flex flex-row systemSelectRow">
+                <div style={{width: "100px"}}>Deployments:</div>
+                <div className="flex-grow-1">
+                    <select
+                        onChange={selectDeployment}
+                        className="customSelector">
+                        {deployments}
+                    </select>
+                </div>
+            </div>
+        </div>
+    );
+}
diff --git a/src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss b/src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss
new file mode 100644
index 0000000..f71cabb
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss
@@ -0,0 +1,27 @@
+.systemContainer {
+    color:white;
+    font-size:13px;
+    padding:0 10px;
+    width: 100%;
+    height: 100%;
+    overflow-y: auto;
+    scrollbar-gutter: stable;
+    scrollbar-color: #47474766 #252526;
+    scrollbar-width: thin;
+}
+
+.systemSelectRow {
+    margin: 5px 0;
+}
+
+.customSelector {
+    border: none;
+    background: #252526;
+    color: white;
+    border-bottom: solid 1px rgb(77, 77, 77);
+    width: 100%;
+}
+
+.customSelector:focus {
+    outline: none;
+}
diff --git a/src/Components/SystemSelectorContainer/SystemSelectorContainer.js b/src/Components/SystemSelectorContainer/SystemSelectorContainer.js
new file mode 100644
index 0000000..07e3132
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/SystemSelectorContainer.js
@@ -0,0 +1,45 @@
+import React, {useEffect, useRef} from "react";
+
+import {SystemSelector} from "./SystemSelector/SystemSelector";
+import {TraceView} from "./TraceView/TraceView";
+import {VerticleHandle} from "./VerticleHandle/VerticleHandle";
+
+import "./SystemSelectorContainer.scss";
+
+/**
+ * Contains the debugger accordian sections.
+ * @return {JSX.Element}
+ */
+export function SystemSelectorContainer () {
+    const debugContainerRef = useRef();
+    const variableStackRef = useRef();
+    const callStackRef = useRef();
+    const breakPointRef = useRef();
+
+    const TITLE_HEIGHT = 20;
+
+    const redrawContainers = () => {
+        const height = debugContainerRef.current.clientHeight;
+        const containerHeight = height - 150;
+        variableStackRef.current.style.height = 150 - TITLE_HEIGHT + "px";
+        callStackRef.current.style.height = containerHeight - TITLE_HEIGHT + "px";
+    };
+
+    useEffect(() => {
+        redrawContainers();
+    }, []);
+
+    return (
+        <div ref={debugContainerRef} className="debug-container w-100 d-flex flex-column">
+            <div className="w-100 title" style={{height: TITLE_HEIGHT + "px"}}>System Selector</div>
+            <div className="section" ref={variableStackRef}>
+                <SystemSelector />
+            </div>
+            <VerticleHandle topDiv={variableStackRef} bottomDiv={callStackRef}/>
+            <div className="w-100 title" style={{height: TITLE_HEIGHT + "px"}}>Traces</div>
+            <div className="section" ref={callStackRef}>
+                <TraceView />
+            </div>
+        </div>
+    );
+}
diff --git a/src/Components/SystemSelectorContainer/SystemSelectorContainer.scss b/src/Components/SystemSelectorContainer/SystemSelectorContainer.scss
new file mode 100644
index 0000000..ffa5f42
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/SystemSelectorContainer.scss
@@ -0,0 +1,14 @@
+.debug-container {
+    width:100%;
+    height:100%;
+}
+
+.debug-container > .section {
+    width:100%;
+}
+
+.title{
+    color: rgb(155, 155, 155);
+    font-size: 12px;
+    margin-left: 10px;
+}
\ No newline at end of file
diff --git a/src/Components/SystemSelectorContainer/TraceView/TraceView.js b/src/Components/SystemSelectorContainer/TraceView/TraceView.js
new file mode 100644
index 0000000..383d77d
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/TraceView/TraceView.js
@@ -0,0 +1,13 @@
+import React from "react";
+
+import "./TraceView.scss";
+
+/**
+ * Contains the system selector components.
+ * @return {JSX.Element}
+ */
+export function TraceView () {
+    return (
+        <></>
+    );
+}
diff --git a/src/Components/SystemSelectorContainer/TraceView/TraceView.scss b/src/Components/SystemSelectorContainer/TraceView/TraceView.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js b/src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js
new file mode 100644
index 0000000..a409a27
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js
@@ -0,0 +1,66 @@
+import React, {useRef} from "react";
+
+import PropTypes from "prop-types";
+
+import "./VerticleHandle.scss";
+
+VerticleHandle.propTypes = {
+    topDiv: PropTypes.object,
+    bottomDiv: PropTypes.object,
+};
+
+/**
+ * Renders a vertically resizable handle for the accordian components.
+ * It accepts two components which are resized when the handle is moved.
+ * @return {JSX.Element}
+ */
+export function VerticleHandle ({topDiv, bottomDiv}) {
+    const handleRef = useRef();
+
+    const MIN_CONTAINER_HEIGHT = 25;
+
+    // Initial values used to calculate delta on mouse move.
+    let downValueY;
+    let topHeight;
+    let bottomHeight;
+
+    const handleMouseDown = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+
+        document.addEventListener("mousemove", handleMouseMove);
+        document.addEventListener("mouseup", handleMouseUp);
+
+        downValueY = e.clientY;
+        topHeight = topDiv.current.getBoundingClientRect().height;
+        bottomHeight = bottomDiv.current.getBoundingClientRect().height;
+
+        handleRef.current.classList.add("handle-active");
+    };
+
+    const handleMouseMove = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+
+        const delta = e.clientY - downValueY;
+        const newPreHeight = topHeight + delta;
+        const newPostHeight = bottomHeight - delta;
+
+        if (newPreHeight > MIN_CONTAINER_HEIGHT && newPostHeight > MIN_CONTAINER_HEIGHT) {
+            topDiv.current.style.height = newPreHeight + "px";
+            bottomDiv.current.style.height = newPostHeight + "px";
+        }
+    };
+
+    const handleMouseUp = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+        document.removeEventListener("mousemove", handleMouseMove);
+        document.removeEventListener("mouseup", handleMouseUp);
+        handleRef.current.classList.remove("handle-active");
+    };
+
+    return (
+        <div ref={handleRef} onMouseDown={handleMouseDown} className="vertical-handle"></div>
+    );
+}
diff --git a/src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.scss b/src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.scss
new file mode 100644
index 0000000..de972d0
--- /dev/null
+++ b/src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.scss
@@ -0,0 +1,10 @@
+.debug-container .vertical-handle {
+    width:100%;
+    height:2px;
+    background-color: #474747;
+    cursor: ns-resize;
+}
+
+.debug-container .handle-active{
+    background-color:#007acc;
+}
\ No newline at end of file
diff --git a/src/Components/TraceDiagram/DagreLayout.js b/src/Components/TraceDiagram/DagreLayout.js
new file mode 100644
index 0000000..9132791
--- /dev/null
+++ b/src/Components/TraceDiagram/DagreLayout.js
@@ -0,0 +1,34 @@
+
+import Dagre from '@dagrejs/dagre';
+
+export const getLayoutedElements = (nodes, edges, options) => {
+    // Reference: https://reactflow.dev/learn/layouting/layouting
+
+    const g = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
+    g.setGraph({ rankdir: options.direction, ranksep: 100 });
+   
+    edges.forEach((edge) => g.setEdge(edge.source, edge.target));
+    nodes.forEach((node) =>
+      g.setNode(node.id, {
+        ...node,
+        width: node.measured?.width ?? 0,
+        height: node.measured?.height ?? 0,
+      }),
+    );
+   
+    Dagre.layout(g);
+   
+    return {
+      nodes: nodes.map((node) => {
+        const position = g.node(node.id);
+        // We are shifting the dagre node position (anchor=center center) to the top left
+        // so it matches the React Flow node anchor point (top left).
+        const x = position.x - (node.measured?.width ?? 0) / 2;
+        const y = position.y - (node.measured?.height ?? 0) / 2;
+   
+        return { ...node, position: { x, y } };
+      }),
+      edges,
+    };
+};
+  
\ No newline at end of file
diff --git a/src/Components/TraceDiagram/SampleNodes.js b/src/Components/TraceDiagram/SampleNodes.js
new file mode 100644
index 0000000..c7e4e1b
--- /dev/null
+++ b/src/Components/TraceDiagram/SampleNodes.js
@@ -0,0 +1,90 @@
+import {
+    Position,
+    MarkerType 
+  } from "@xyflow/react";
+
+const nodeDefaults = {
+  sourcePosition: Position.Bottom,
+  targetPosition: Position.Top,
+};
+
+export const initialNodes = [
+  {
+    id: "A",
+    type: "input",
+    position: { x: 250, y: 0 },
+    data: { label: "Simulted Client" }
+  },
+  {
+    id: "B",
+    position: { x: 250, y: 150 },
+    data: { label: "Job Handler" }
+  },
+  {
+    id: "C",
+    position: { x: 250, y: 300 },
+    data: { label: "Bubble Sort Worker" }
+  },
+  {
+    id: "D",
+    position: { x: 250, y: 450 },
+    data: { label: "Job Handler" }
+  },
+  {
+    id: "E",
+    type: "output",
+    position: { x: 250, y: 600 },
+    data: { label: "Simulated Client" }
+  },
+];
+
+const marker = {
+  type: MarkerType.ArrowClosed,
+  width: 20,
+  height: 20,
+  color: '#FF0072',
+}
+
+const arrowStyle = {
+  strokeWidth: 2,
+  stroke: '#FF0072',
+}
+
+export const initialEdges = [
+  {
+    id: "A-B",
+    source: "A",
+    target: "B",
+    animated: true,
+    markerEnd: marker,
+    style: arrowStyle,
+    // label: 'Submit Random Job',
+  },
+  {
+    id: "B-C",
+    source: "B",
+    target: "C",
+    animated: true,
+    markerEnd: marker,
+    style: arrowStyle,
+    // label: 'Distribute Storing Job to Worker',
+  },
+  {
+    id: "C-D",
+    source: "C",
+    target: "D",
+    animated: true,
+    markerEnd: marker,
+    style: arrowStyle,
+    // label: 'Return Finished Job to Handler',
+  },
+  {
+    id: "D-E",
+    source: "D",
+    target: "E",
+    animated: true,
+    markerEnd: marker,
+    style: arrowStyle,
+    // label: 'Return Finished Job to Client',
+  },
+];
\ No newline at end of file
diff --git a/src/Components/TraceDiagram/TraceDiagram.jsx b/src/Components/TraceDiagram/TraceDiagram.jsx
new file mode 100644
index 0000000..cb7e37f
--- /dev/null
+++ b/src/Components/TraceDiagram/TraceDiagram.jsx
@@ -0,0 +1,109 @@
+import React, {useCallback, useEffect, useState} from "react";
+
+import {
+    Controls,
+    Panel,
+    ReactFlow,
+    ReactFlowProvider,
+    useEdgesState,
+    useNodesState,
+    useReactFlow
+} from "@xyflow/react";
+import PropTypes from "prop-types";
+
+import {getLayoutedElements} from "./DagreLayout.js";
+import {getNodesFromTrace} from "./helper.js";
+
+import "@xyflow/react/dist/style.css";
+
+const Flow = ({trace}) => {
+    const {fitView} = useReactFlow();
+    const [colorMode, setColorMode] = useState("dark");
+    const [nodes, setNodes, onNodesChange] = useNodesState([]);
+    const [edges, setEdges, onEdgesChange] = useEdgesState([]);
+
+    const onChange = (evt) =>
+        setColorMode(evt.target.value);
+
+    const onLayout = useCallback(
+        (direction) => {
+            const layouted = getLayoutedElements(nodes, edges, {direction});
+
+            setNodes([...layouted.nodes]);
+            setEdges([...layouted.edges]);
+
+            fitView();
+        },
+        [nodes, edges]
+    );
+
+    useEffect(() => {
+        if (trace) {
+            const flowInfo = getNodesFromTrace(trace);
+
+            const layouted = getLayoutedElements(
+                flowInfo.nodes,
+                flowInfo.edges,
+                {direction: "TB"}
+            );
+
+            setNodes([...layouted.nodes]);
+            setEdges([...layouted.edges]);
+
+            fitView();
+        }
+    }, [trace]);
+
+    const onNodeClick = (e, node) => {
+        console.log(e, node);
+    };
+
+    return (
+        <ReactFlow
+            nodes={nodes}
+            edges={edges}
+            onNodesChange={onNodesChange}
+            onEdgesChange={onEdgesChange}
+            colorMode={colorMode}
+            onNodeClick={onNodeClick}
+            fitView
+        >
+            <Controls />
+
+            <Panel position="top-right">
+                <select onChange={onChange} data-testid="colormode-select">
+                    <option value="dark">dark</option>
+                    <option value="light">light</option>
+                    <option value="system">system</option>
+                </select>
+            </Panel>
+
+            <Panel position="top-left">
+                <button onClick={() => onLayout("TB")}>vertical layout</button>
+                <button onClick={() => onLayout("LR")}>horizontal layout</button>
+            </Panel>
+        </ReactFlow>
+    );
+};
+
+Flow.propTypes = {
+    trace: PropTypes.array,
+};
+
+export const TraceDiagram = ({traces}) => {
+    const [traceList, setTraceList] = useState();
+
+    useEffect(() => {
+        setTraceList(traces);
+    }, [traces]);
+
+    return (
+        <ReactFlowProvider>
+            <Flow trace={traceList} />
+        </ReactFlowProvider>
+    );
+};
+
+TraceDiagram.propTypes = {
+    traces: PropTypes.array,
+};
diff --git a/src/Components/TraceDiagram/TraceDiagram.scss b/src/Components/TraceDiagram/TraceDiagram.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/Components/TraceDiagram/helper.js b/src/Components/TraceDiagram/helper.js
new file mode 100644
index 0000000..bf00621
--- /dev/null
+++ b/src/Components/TraceDiagram/helper.js
@@ -0,0 +1,64 @@
+import {MarkerType} from "@xyflow/react";
+
+const marker = {
+    type: MarkerType.ArrowClosed,
+    width: 20,
+    height: 20,
+    color: "#FF0072",
+};
+
+const arrowStyle = {
+    strokeWidth: 2,
+    stroke: "#FF0072",
+};
+
+/**
+ * Returns react flow nodes and edges from the given trace.
+ * @param {Object} trace
+ * @returns {Array} An array co
+ */
+
+
+export const getNodesFromTrace = (trace) => {
+    const edges = [];
+    const nodes = [];
+
+    // Validate input
+    if (!Array.isArray(trace) || trace.length === 0) {
+        return { nodes, edges };
+    }
+
+    trace.forEach((node, index) => {
+        node.flowId = String(index) + node.adliExecutionId;
+        const flowNode = {
+            id: node.flowId,
+            position: {x: 250, y: index * 200}, // Consider making x position configurable
+            data: {label: node.programName},
+        };
+        flowNode.sourceNode = node;
+
+        if (index == 0) {
+            flowNode.type = "input";
+        }
+
+        if (index > 0) {
+            const prevNode = trace[index - 1];
+            const edge = {
+                id: prevNode.flowId + "-" + node.flowId,
+                source: prevNode.flowId,
+                target: node.flowId,
+                animated: true,
+                markerEnd: marker,
+                style: arrowStyle,
+            };
+            edges.push(edge);
+        }
+
+        nodes.push(flowNode);
+    });
+
+    return {
+        nodes: nodes,
+        edges: edges,
+    };
+};
diff --git a/src/Components/TraceDiagram/index.js b/src/Components/TraceDiagram/index.js
new file mode 100644
index 0000000..bdc2693
--- /dev/null
+++ b/src/Components/TraceDiagram/index.js
@@ -0,0 +1 @@
+export * from "./TraceDiagram.jsx"
\ No newline at end of file
diff --git a/src/Providers/ASPProviders.js b/src/Providers/ASPProviders.js
index 4710416..44636c0 100644
--- a/src/Providers/ASPProviders.js
+++ b/src/Providers/ASPProviders.js
@@ -4,7 +4,8 @@ import PropTypes from "prop-types";
 import useWebSocket, {ReadyState} from "react-use-websocket";
 
 import FileTreeContext from "./FileTreeContext";
-import UniqueTraceContext from "./UniqueTraceContext";
+import System from "./System";
+import SystemsContext from "./SystemsContext";
 
 ASPProviders.propTypes = {
     children: PropTypes.object,
@@ -23,7 +24,7 @@ function ASPProviders ({children}) {
     const [messageHistory, setMessageHistory] = useState([]);
 
     const [fileTree, setFileTree] = useState();
-    const [uniqueTrace, setUniqueTrace] = useState();
+    const [systemsList, setSystemsList] = useState(null);
 
     // Open websocket connection and reconnect when it closes
     const {sendJsonMessage, lastJsonMessage, readyState} = useWebSocket(
@@ -47,9 +48,9 @@ function ASPProviders ({children}) {
     useEffect(() => {
         console.debug(`Connection state: ${connectionStatus}`);
         if (readyState === ReadyState.OPEN) {
-            console.log("RUNNING");
-            sendJsonMessage({code: 2});
-            sendJsonMessage({code: 1});
+            sendJsonMessage(
+                {queryType: "GET_SYSTEMS"}
+            );
         }
     }, [readyState]);
 
@@ -62,22 +63,26 @@ function ASPProviders ({children}) {
     }, [lastJsonMessage]);
 
 
+    const loadSystems = (systems) => {
+        const _systems = [];
+        systems.forEach((system, index) => {
+            _systems.push(new System(system));
+        });
+        setSystemsList(_systems);
+    };
+
     const handleMessage = (msg) => {
-        if (msg.code == 1) {
-            console.log("Unique System Traces:", msg.response);
-            setUniqueTrace(msg.response);
-        } else if (msg.code == 2) {
-            console.log("System File Trees:", msg.response);
-            setFileTree(msg.response);
+        if (msg.queryType == "GET_SYSTEMS") {
+            loadSystems(msg.response);
         }
     };
 
     return (
         <>
             <FileTreeContext.Provider value={{fileTree}}>
-                <UniqueTraceContext.Provider value={{uniqueTrace}}>
+                <SystemsContext.Provider value={{systemsList}}>
                     {children}
-                </UniqueTraceContext.Provider>
+                </SystemsContext.Provider>
             </FileTreeContext.Provider>
         </>
     );
diff --git a/src/Providers/System.js b/src/Providers/System.js
new file mode 100644
index 0000000..3fdaaed
--- /dev/null
+++ b/src/Providers/System.js
@@ -0,0 +1,20 @@
+
+/**
+ * This class contains all the properties of a system.
+ */
+class System {
+    /**
+     * @param {Object} systemInfo Information about the loaded system.
+     */
+    constructor (systemInfo) {
+        this.id = systemInfo.system_id + "_" + systemInfo.version;
+        this.sysId = String(systemInfo.system_id);
+        this.version = String(systemInfo.version);
+        this.programs = systemInfo.programs;
+        this.deployments = systemInfo.deployments;
+
+        console.log("Created System:", this.sysId, this.version);
+    }
+}
+
+export default System;
diff --git a/src/Providers/UniqueTraceContext.js b/src/Providers/SystemsContext.js
similarity index 58%
rename from src/Providers/UniqueTraceContext.js
rename to src/Providers/SystemsContext.js
index d1a3532..3320780 100644
--- a/src/Providers/UniqueTraceContext.js
+++ b/src/Providers/SystemsContext.js
@@ -1,6 +1,6 @@
 import {createContext} from "react";
 
 // This context stores the unique traces extracted by system processor.
-const UniqueTraceContext = createContext();
+const SystemsContext = createContext();
 
-export default UniqueTraceContext;
+export default SystemsContext;
diff --git a/src/Viewer/FileViewer/FileViewer.js b/src/Viewer/FileViewer/FileViewer.js
index 385a761..b52a104 100644
--- a/src/Viewer/FileViewer/FileViewer.js
+++ b/src/Viewer/FileViewer/FileViewer.js
@@ -1,81 +1,18 @@
 import React, {useEffect, useRef, useState} from "react";
 
-import GridLayout from "react-grid-layout";
+import {TraceDiagram} from "../../Components/TraceDiagram/TraceDiagram";
+import systemtrace from "./systemtrace.json";
 
-import {MonacoInstance} from "../../Components/MonacoInstance/MonacoInstance";
-
-import "react-grid-layout/css/styles.css";
-import "react-resizable/css/styles.css";
 import "./FileViewer.scss";
-import "monaco-editor/min/vs/editor/editor.main.css";
 
 /**
  * Renders the monaco editor and the tabs.
  * @return {JSX.Element}
  */
 export function FileViewer () {
-    const viewerRef = useRef();
-
-    const [showGrid, setShowGrid] = useState(false);
-    const [editorWidth, setEditorWidth] = useState();
-    const [editorHeight, setEditorHeight] = useState();
-
-    const [layout, setLayout] = useState();
-
-    useEffect(() => {
-        const updateDimensions = () => {
-            if (viewerRef.current) {
-                const height = viewerRef.current.getBoundingClientRect().height/4;
-                const width = viewerRef.current.getBoundingClientRect().width;
-                setEditorHeight(height);
-                setEditorWidth(width);
-            }
-        };
-
-        updateDimensions();
-
-        setLayout([
-            {i: "a", x: 0, y: 0, w: 6, h: 1},
-            {i: "b", x: 6, y: 0, w: 6, h: 1},
-            {i: "c", x: 0, y: 8, w: 6, h: 1},
-            {i: "d", x: 6, y: 8, w: 6, h: 1},
-        ]);
-
-        setShowGrid(true);
-
-        const observer = new ResizeObserver(updateDimensions);
-        observer.observe(viewerRef.current);
-        return () => {
-            observer.disconnect();
-        };
-    }, []);
-
     return (
-        <div ref={viewerRef} className="file-view-container d-flex flex-row">
-            {showGrid &&
-                <GridLayout
-                    className="layout"
-                    layout={layout}
-                    cols={12}
-                    rowHeight={editorHeight}
-                    maxRows={3}
-                    width={editorWidth}
-                    margin={[5, 5]}
-                >
-                    <div key="a">
-                        <MonacoInstance/>
-                    </div>
-                    <div key="b">
-                        <MonacoInstance/>
-                    </div>
-                    <div key="c">
-                        <MonacoInstance/>
-                    </div>
-                    <div key="d">
-                        <MonacoInstance/>
-                    </div>
-                </GridLayout>
-            }
-        </div>
+        <>
+            <TraceDiagram traces={systemtrace} />
+        </>
     );
 }
diff --git a/src/Viewer/FileViewer/systemtrace.json b/src/Viewer/FileViewer/systemtrace.json
new file mode 100644
index 0000000..53f0433
--- /dev/null
+++ b/src/Viewer/FileViewer/systemtrace.json
@@ -0,0 +1,63 @@
+[
+    {
+        "adliExecutionId": "9374c35d-644a-47e3-b1e7-eb54e7c0b87c",
+        "adliExecutionIndex": 34,
+        "adliValue": {
+            "asp_uid": "a1deab95-33fd-4b50-8d04-72c3923b8e8a",
+            "code": 1,
+            "type": "bubbleSort",
+            "worker": true
+        },
+        "funcName": "send_response",
+        "outputName": "response",
+        "programName": "Bubble Sort",
+        "timestamp": 1745265678864,
+        "type": "adli_output",
+        "uid": "e1fbbb5d-1d2c-4e56-bbb3-ae7c18112121"
+    },
+    {
+        "adliExecutionId": "9374c35d-644a-47e3-b1e7-eb54e7c0b87c",
+        "adliExecutionIndex": 34,
+        "adliValue": {
+            "asp_uid": "a1deab95-33fd-4b50-8d04-72c3923b8e8a",
+            "code": 1,
+            "type": "bubbleSort",
+            "worker": true
+        },
+        "funcName": "handle_message",
+        "output": [
+            {
+                "adliExecutionId": "0365447b-5d5e-4500-ac11-d8e718569c6f",
+                "adliExecutionIndex": 62,
+                "adliValue": {
+                    "asp_uid": "a1deab95-33fd-4b50-8d04-72c3923b8e8a",
+                    "code": 1,
+                    "type": "bubbleSort",
+                    "worker": true
+                },
+                "funcName": "send_to_worker",
+                "outputName": "message",
+                "programName": "Job Handler",
+                "timestamp": 1745265678865,
+                "type": "adli_output"
+            }
+        ],
+        "programName": "Job Handler",
+        "timestamp": 1745265678864,
+        "type": "adli_input"
+    },
+    {
+        "adliExecutionId": "0365447b-5d5e-4500-ac11-d8e718569c6f",
+        "adliExecutionIndex": 62,
+        "adliValue": {
+            "asp_uid": "a1deab95-33fd-4b50-8d04-72c3923b8e8a",
+            "code": 1,
+            "type": "bubbleSort",
+            "worker": true
+        },
+        "funcName": "handle_message",
+        "programName": "Bubble Sort",
+        "timestamp": 1745265678865,
+        "type": "adli_input"
+    }
+]
\ No newline at end of file
diff --git a/src/Viewer/SideContainer/SideContainer.js b/src/Viewer/SideContainer/SideContainer.js
index 946477a..40d9636 100644
--- a/src/Viewer/SideContainer/SideContainer.js
+++ b/src/Viewer/SideContainer/SideContainer.js
@@ -1,6 +1,7 @@
 import React, {useRef, useState} from "react";
 
 import {Diagram3, Gear, Keyboard} from "react-bootstrap-icons";
+import { SystemSelectorContainer } from "../../Components/SystemSelectorContainer/SystemSelectorContainer";
 
 import "./SideContainer.scss";
 
@@ -15,7 +16,7 @@ export function SideContainer () {
     const handle = useRef();
 
     const SIDE_MENU_WIDTH = 50;
-    const ACCORDIAN_WIDTH = 200;
+    const ACCORDIAN_WIDTH = 400;
     const MIN_EDITOR_WIDTH = 400;
     const MIN_ACCORDIAN_WIDTH = 200;
     const MAX_ACCORDIAN_WIDTH = document.body.clientWidth - SIDE_MENU_WIDTH - MIN_EDITOR_WIDTH;
@@ -51,7 +52,7 @@ export function SideContainer () {
 
     const getActiveMenuComponent = () => {
         if (activeMenu === 1) {
-            return <></>;
+            return <SystemSelectorContainer/>;
         } else if (activeMenu === 2) {
             return <></>;
         } else if (activeMenu === 3) {


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 9**

<details>
<summary>🧹 Nitpick comments (36)</summary><blockquote>

<details>
<summary>src/Providers/SystemsContext.js (1)</summary><blockquote>

`3-4`: **Update the comment to match the new context purpose**

The comment still refers to "unique traces" while the context has been renamed to `SystemsContext`. This creates inconsistency and could confuse developers. Consider updating the comment to reflect that this context now stores systems data rather than trace data.

```diff
- // This context stores the unique traces extracted by system processor.
+ // This context stores the systems data loaded from ASP.
```

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.scss (1)</summary><blockquote>

`1-10`: **Fix spelling: "Verticle" should be "Vertical"**

There's a spelling error in both the filename and CSS classes. "Verticle" should be "Vertical" (with an "a").

Consider renaming the file to `VerticalHandle.scss` and updating the classes:

```diff
- .debug-container .vertical-handle {
+ .debug-container .vertical-handle {
  /* No change to class name here as it's already correct */
```

This should also be fixed in the corresponding JS component file and any imports.

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/helper.js (3)</summary><blockquote>

`15-21`: **Complete the JSDoc comment and remove empty line**

The JSDoc comment is incomplete and there's an empty line separating it from the function declaration, which can break documentation tools.

```diff
 /**
  * Returns react flow nodes and edges from the given trace.
- * @param {Object} trace
- * @returns {Array} An array co
+ * @param {Array} trace Array of trace data objects
+ * @returns {Object} An object containing nodes and edges arrays for React Flow
  */
-
 export const getNodesFromTrace = (trace) => {
```

---

`35-37`: **Use strict equality comparison**

For consistency and to avoid potential type coercion issues, use strict equality (`===`) instead of loose equality (`==`).

```diff
- if (index == 0) {
+ if (index === 0) {
     flowNode.type = "input";
 }
```

---

`1-59`: **Consider adding advanced edge styling based on trace relationship types**

The current implementation creates a simple sequential flow diagram. For a more informative visualization, consider enhancing edge styling based on trace relationship types:

1. Add different colors/styles for different types of communications between systems
2. Include edge labels with function names or message types
3. Use different markers for input vs. output traces

This would help users better understand the relationship between connected nodes in the trace diagram.

</blockquote></details>
<details>
<summary>src/Providers/System.js (1)</summary><blockquote>

`17-17`: **Consider removing or conditionally using console.log**

Console logs should generally be avoided in production code. Consider using a debug flag or removing this log statement.


```diff
-console.log("Created System:", this.sysId, this.version);
+// Only log in development environment
+if (process.env.NODE_ENV === 'development') {
+    console.log("Created System:", this.sysId, this.version);
+}
```

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/index.js (1)</summary><blockquote>

`1-1`: **Missing semicolon**

Add a semicolon at the end of the line to conform to JavaScript conventions and fix the ESLint error.


```diff
-export * from "./TraceDiagram.jsx"
+export * from "./TraceDiagram.jsx";
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 ESLint</summary>

[error] 1-1: Missing semicolon.

(semi)

</details>

</details>

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/TraceView/TraceView.js (2)</summary><blockquote>

`5-8`: **Incorrect JSDoc comment**

The JSDoc comment incorrectly states that this component "Contains the system selector components" when it actually appears to be a TraceView component.


```diff
/**
- * Contains the system selector components.
+ * Displays trace information for the selected system.
 * @return {JSX.Element}
 */
```

---

`10-12`: **Empty component implementation**

The component currently renders an empty fragment. Consider adding a TODO comment or placeholder content to indicate future implementation plans.


```diff
export function TraceView () {
    return (
-        <></>
+        <>
+            {/* TODO: Implement trace view UI components */}
+            <div className="trace-view-placeholder">
+                Select a system, version, and deployment to view traces
+            </div>
+        </>
    );
}
```

</blockquote></details>
<details>
<summary>src/Viewer/SideContainer/SideContainer.js (1)</summary><blockquote>

`19-19`: **Spelling error in variable name**

The variable `ACCORDIAN_WIDTH` contains a spelling error. The correct spelling is "accordion".


```diff
-    const ACCORDIAN_WIDTH = 400;
+    const ACCORDION_WIDTH = 400;
```

This would need to be updated in other places where the variable is used as well.

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelectorContainer.scss (2)</summary><blockquote>

`1-4`: **Consider renaming `.debug-container` to something more production-appropriate.**

The class name `.debug-container` suggests temporary or debugging code, but this appears to be a permanent component for the production system. A more descriptive name like `.system-selector-container` or `.asv-container` would better reflect its purpose in the application.

```diff
-.debug-container {
+.system-selector-container {
    width:100%;
    height:100%;
}
```

---

`6-8`: **Ensure selector consistency with parent class name.**

If you rename the parent container class as suggested above, remember to update this child selector to match.

```diff
-.debug-container > .section {
+.system-selector-container > .section {
    width:100%;
}
```

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss (1)</summary><blockquote>

`1-11`: **Add consistent spacing in CSS properties.**

For better readability and maintainability, add consistent spacing after colons in CSS properties.

```diff
.systemContainer {
-    color:white;
-    font-size:13px;
-    padding:0 10px;
+    color: white;
+    font-size: 13px;
+    padding: 0 10px;
    width: 100%;
    height: 100%;
    overflow-y: auto;
    scrollbar-gutter: stable;
    scrollbar-color: #47474766 #252526;
    scrollbar-width: thin;
}
```

</blockquote></details>
<details>
<summary>src/Providers/ASPProviders.js (3)</summary><blockquote>

`27-27`: **Initialize systemsList with an empty array instead of null.**

Using `null` as the initial state for a list can lead to null-checking requirements in components that consume this context. An empty array is a more appropriate initial value.

```diff
-    const [systemsList, setSystemsList] = useState(null);
+    const [systemsList, setSystemsList] = useState([]);
```

---

`66-72`: **Refactor loadSystems for conciseness and remove unused parameter.**

The `index` parameter is unused, and the function could be more concisely written using `map()`.

```diff
const loadSystems = (systems) => {
-    const _systems = [];
-    systems.forEach((system, index) => {
-        _systems.push(new System(system, sendJsonMessage));
-    });
-    setSystemsList(_systems);
+    const _systems = systems.map(system => new System(system, sendJsonMessage));
+    setSystemsList(_systems);
};
```

---

`75-75`: **Use strict equality (===) for comparison.**

JavaScript best practices recommend using strict equality (`===`) instead of loose equality (`==`) to avoid unexpected type coercion.

```diff
-        if (msg.queryType == "GET_SYSTEMS") {
+        if (msg.queryType === "GET_SYSTEMS") {
```

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/DagreLayout.js (4)</summary><blockquote>

`1-3`: **Remove the empty line at the beginning of the file.**

Good coding practices suggest avoiding unnecessary empty lines, especially at the beginning of a file.

```diff
-

import Dagre from '@dagrejs/dagre';

```

---

`4-8`: **Add input validation for the options parameter.**

The function doesn't verify that `options.direction` exists before using it, which could lead to errors if the options object is incomplete.

```diff
export const getLayoutedElements = (nodes, edges, options) => {
    // Reference: https://reactflow.dev/learn/layouting/layouting

+    if (!nodes || !edges || !options || !options.direction) {
+        console.error('getLayoutedElements: Missing required parameters');
+        return { nodes, edges };
+    }

    const g = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
    g.setGraph({ rankdir: options.direction, ranksep: 100 });
```

---

`10-18`: **Add error handling for unexpected data structures.**

The function assumes all nodes have an `id` property and all edges have `source` and `target` properties. Adding error handling would make the code more robust.

```diff
-    edges.forEach((edge) => g.setEdge(edge.source, edge.target));
-    nodes.forEach((node) =>
-      g.setNode(node.id, {
-        ...node,
-        width: node.measured?.width ?? 0,
-        height: node.measured?.height ?? 0,
-      }),
-    );
+    edges.forEach((edge) => {
+        if (edge.source && edge.target) {
+            g.setEdge(edge.source, edge.target);
+        }
+    });
+    
+    nodes.forEach((node) => {
+        if (node.id) {
+            g.setNode(node.id, {
+                ...node,
+                width: node.measured?.width ?? 0,
+                height: node.measured?.height ?? 0,
+            });
+        }
+    });
```

---

`19-33`: **Wrap the layout calculation in try/catch to handle potential exceptions.**

Dagre operations might throw exceptions with certain inputs. Adding a try/catch block would prevent crashes.

```diff
-    Dagre.layout(g);
-   
-    return {
-      nodes: nodes.map((node) => {
-        const position = g.node(node.id);
-        // We are shifting the dagre node position (anchor=center center) to the top left
-        // so it matches the React Flow node anchor point (top left).
-        const x = position.x - (node.measured?.width ?? 0) / 2;
-        const y = position.y - (node.measured?.height ?? 0) / 2;
-   
-        return { ...node, position: { x, y } };
-      }),
-      edges,
-    };
+    try {
+        Dagre.layout(g);
+       
+        return {
+            nodes: nodes.map((node) => {
+                if (!node.id) return node;
+                
+                const position = g.node(node.id);
+                if (!position) return node;
+                
+                // We are shifting the dagre node position (anchor=center center) to the top left
+                // so it matches the React Flow node anchor point (top left).
+                const x = position.x - (node.measured?.width ?? 0) / 2;
+                const y = position.y - (node.measured?.height ?? 0) / 2;
+       
+                return { ...node, position: { x, y } };
+            }),
+            edges,
+        };
+    } catch (error) {
+        console.error('Error calculating layout:', error);
+        return { nodes, edges };
+    }
```

</blockquote></details>
<details>
<summary>src/Viewer/FileViewer/FileViewer.js (1)</summary><blockquote>

`1-1`: **Remove unused imports**

The component imports `useEffect`, `useRef`, and `useState` from React, but none of these hooks are actually used in the implementation.

```diff
-import React, {useEffect, useRef, useState} from "react";
+import React from "react";
```

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/TraceDiagram.jsx (4)</summary><blockquote>

`57-59`: **Enhance node click handler for better user interaction**

The current `onNodeClick` handler only logs to the console, which doesn't provide any user-visible functionality.

Consider implementing a more meaningful interaction, such as displaying node details in a panel or highlighting connected nodes:

```diff
const onNodeClick = (e, node) => {
-   console.log(e, node);
+   // For now we log, but in future PR this could:
+   // 1. Show node details in a sidebar
+   // 2. Highlight connected nodes
+   // 3. Allow editing node properties
+   console.log("Node clicked:", node.sourceNode || node.data);
};
```

---

`89-91`: **Enhance PropTypes with more specific type definitions**

The current PropTypes definition for `trace` is very generic (`PropTypes.array`).

Consider using a more specific PropType to better document the expected data structure:

```diff
Flow.propTypes = {
-   trace: PropTypes.array,
+   trace: PropTypes.arrayOf(PropTypes.shape({
+       adliExecutionId: PropTypes.string.isRequired,
+       programName: PropTypes.string.isRequired,
+       // Add other expected properties here
+   })),
};
```

---

`93-105`: **Consider memoizing the Flow component for better performance**

The TraceDiagram component re-renders the Flow component whenever traces change, but doesn't memoize the component which could lead to unnecessary re-renders.

Consider using React.memo for the Flow component:

```diff
-const Flow = ({trace}) => {
+const Flow = React.memo(({trace}) => {
    // Component implementation
-};
+});
```

Also, you could use `useMemo` for the traceList state to avoid unnecessary state updates:

```diff
export const TraceDiagram = ({traces}) => {
-   const [traceList, setTraceList] = useState();
+   const traceList = useMemo(() => traces, [traces]);

-   useEffect(() => {
-       setTraceList(traces);
-   }, [traces]);

    return (
        <ReactFlowProvider>
            <Flow trace={traceList} />
        </ReactFlowProvider>
    );
};
```

---

`107-109`: **Enhance PropTypes with more specific type definitions**

Similar to the Flow component, the TraceDiagram PropTypes could be more specific.

```diff
TraceDiagram.propTypes = {
-   traces: PropTypes.array,
+   traces: PropTypes.arrayOf(PropTypes.shape({
+       adliExecutionId: PropTypes.string.isRequired,
+       programName: PropTypes.string.isRequired,
+       // Add other expected properties here
+   })),
};
```

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelectorContainer.js (5)</summary><blockquote>

`9-12`: **Update JSDoc comment to match implementation**

The JSDoc comment references "debugger accordian sections" which doesn't match the current implementation of a system selector container.

```diff
/**
- * Contains the debugger accordian sections.
+ * Contains the system selector and trace view sections with resizable divider.
 * @return {JSX.Element}
 */
```

---

`13-18`: **Unused ref and naming inconsistency**

The component defines `breakPointRef` but doesn't use it anywhere in the code. Also, there's a naming inconsistency with some refs suggesting a debugger context rather than a system selector context.

```diff
export function SystemSelectorContainer () {
-   const debugContainerRef = useRef();
-   const variableStackRef = useRef();
-   const callStackRef = useRef();
-   const breakPointRef = useRef();
+   const containerRef = useRef();
+   const systemSelectorRef = useRef();
+   const traceViewRef = useRef();
```

---

`21-26`: **Improve container sizing logic with CSS variables**

The current approach uses hard-coded values and directly manipulates DOM styles, which could be improved for maintainability and responsiveness.

Consider using CSS variables and more descriptive calculations:

```diff
const redrawContainers = () => {
-   const height = debugContainerRef.current.clientHeight;
-   const containerHeight = height - 150;
-   variableStackRef.current.style.height = 150 - TITLE_HEIGHT + "px";
-   callStackRef.current.style.height = containerHeight - TITLE_HEIGHT + "px";
+   const totalHeight = containerRef.current.clientHeight;
+   const systemSelectorHeight = 150; // Could be made configurable
+   const traceViewHeight = totalHeight - systemSelectorHeight - (TITLE_HEIGHT * 2) - 2; // 2px for borders/handles
+   
+   systemSelectorRef.current.style.height = (systemSelectorHeight - TITLE_HEIGHT) + "px";
+   traceViewRef.current.style.height = (traceViewHeight - TITLE_HEIGHT) + "px";
};
```

---

`32-44`: **Correct ref names in the JSX structure**

After updating the ref names as suggested earlier, make sure to update them in the JSX structure as well.

```diff
return (
-   <div ref={debugContainerRef} className="debug-container w-100 d-flex flex-column">
+   <div ref={containerRef} className="debug-container w-100 d-flex flex-column">
        <div className="w-100 title" style={{height: TITLE_HEIGHT + "px"}}>System Selector</div>
-       <div className="section" ref={variableStackRef}>
+       <div className="section" ref={systemSelectorRef}>
            <SystemSelector />
        </div>
-       <VerticleHandle topDiv={variableStackRef} bottomDiv={callStackRef}/>
+       <VerticleHandle topDiv={systemSelectorRef} bottomDiv={traceViewRef}/>
        <div className="w-100 title" style={{height: TITLE_HEIGHT + "px"}}>Traces</div>
-       <div className="section" ref={callStackRef}>
+       <div className="section" ref={traceViewRef}>
            <TraceView />
        </div>
    </div>
);
```

---

`38-38`: **Fix typo in component name "VerticleHandle"**

The component is named "VerticleHandle" which appears to be a typo.

The correct spelling should be "VerticalHandle". Consider renaming the component and its file in a future PR for better code maintenance.

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/SampleNodes.js (3)</summary><blockquote>

`10-17`: **Fix typo in node label**

There's a typo in the label for the first node.

```diff
-    data: { label: "Simulted Client" }
+    data: { label: "Simulated Client" }
```

---

`41-52`: **Add missing semicolons and ensure consistent styling**

There are missing semicolons at the end of two object declarations.

```diff
const marker = {
  type: MarkerType.ArrowClosed,
  width: 20,
  height: 20,
  color: '#FF0072',
-}
+};

const arrowStyle = {
  strokeWidth: 2,
  stroke: '#FF0072',
-}
+};
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 ESLint</summary>

[error] 46-47: Missing semicolon.

(semi)

---

[error] 51-52: Missing semicolon.

(semi)

</details>

</details>

---

`6-9`: **Unused nodeDefaults object**

The `nodeDefaults` object is defined but never used in the file.

Either apply the defaults to the nodes or remove the unused code:

```diff
-const nodeDefaults = {
-  sourcePosition: Position.Bottom,
-  targetPosition: Position.Top,
-};

export const initialNodes = [
  {
    id: "A",
    type: "input",
+   sourcePosition: Position.Bottom,
+   targetPosition: Position.Top,
    position: { x: 250, y: 0 },
    data: { label: "Simulated Client" }
  },
  // Apply to other nodes similarly
```

Alternatively, if this is intentional for future use, add a comment explaining its purpose.

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js (1)</summary><blockquote>

`49-49`: **Use strict equality comparison**

You're using loose equality (`==`) for version comparison. This should be replaced with strict equality (`===`) to avoid potential type coercion issues.

```diff
-(obj) => {return (obj.sysId === systemid && obj.version == version);}
+(obj) => {return (obj.sysId === systemid && obj.version === version);}
```

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js (2)</summary><blockquote>

`1-66`: **Correct component and file naming: "Verticle" should be "Vertical"**

The component name and file references contain a typo: "Verticle" should be "Vertical". This affects the component name, file name, and imports.

This would require renaming the file and updating imports across the codebase. The component definition should be:

```diff
-export function VerticleHandle ({topDiv, bottomDiv}) {
+export function VerticalHandle ({topDiv, bottomDiv}) {
```

Also update the import statement:

```diff
-import "./VerticleHandle.scss";
+import "./VerticalHandle.scss";
```

And the PropTypes definition:

```diff
-VerticleHandle.propTypes = {
+VerticalHandle.propTypes = {
```

---

`13-13`: **Fix typo in JSDoc comment**

There's a typo in the JSDoc comment: "accordian" should be "accordion".

```diff
-/**
- * Renders a vertically resizable handle for the accordian components.
- * It accepts two components which are resized when the handle is moved.
- * @return {JSX.Element}
- */
+/**
+ * Renders a vertically resizable handle for the accordion components.
+ * It accepts two components which are resized when the handle is moved.
+ * @return {JSX.Element}
+ */
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 2488b22b10a201373a5462c978d5f412d804f1c1 and 12f4196cf57aa43ff42a2e837063a72a73ef3f0b.

</details>

<details>
<summary>📒 Files selected for processing (19)</summary>

* `package.json` (1 hunks)
* `src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js` (1 hunks)
* `src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss` (1 hunks)
* `src/Components/SystemSelectorContainer/SystemSelectorContainer.js` (1 hunks)
* `src/Components/SystemSelectorContainer/SystemSelectorContainer.scss` (1 hunks)
* `src/Components/SystemSelectorContainer/TraceView/TraceView.js` (1 hunks)
* `src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js` (1 hunks)
* `src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.scss` (1 hunks)
* `src/Components/TraceDiagram/DagreLayout.js` (1 hunks)
* `src/Components/TraceDiagram/SampleNodes.js` (1 hunks)
* `src/Components/TraceDiagram/TraceDiagram.jsx` (1 hunks)
* `src/Components/TraceDiagram/helper.js` (1 hunks)
* `src/Components/TraceDiagram/index.js` (1 hunks)
* `src/Providers/ASPProviders.js` (4 hunks)
* `src/Providers/System.js` (1 hunks)
* `src/Providers/SystemsContext.js` (1 hunks)
* `src/Viewer/FileViewer/FileViewer.js` (1 hunks)
* `src/Viewer/FileViewer/systemtrace.json` (1 hunks)
* `src/Viewer/SideContainer/SideContainer.js` (3 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧠 Learnings (1)</summary>

<details>
<summary>src/Viewer/FileViewer/FileViewer.js (1)</summary>

```
Learnt from: vishalpalaniappan
PR: vishalpalaniappan/automated-system-viewer#2
File: src/Viewer/FileViewer/FileViewer.js:66-77
Timestamp: 2025-03-07T07:22:23.983Z
Learning: In the automated-system-viewer project, components in the initial layout setup (particularly Monaco instances in the FileViewer component) are currently placeholders that will be refined in future PRs. The developer is experimenting with react-grid-layout to determine the optimal application structure.
```

</details>

</details><details>
<summary>🧬 Code Graph Analysis (9)</summary>

<details>
<summary>src/Viewer/SideContainer/SideContainer.js (1)</summary><blockquote>

<details>
<summary>src/Components/SystemSelectorContainer/SystemSelectorContainer.js (1)</summary>

* `SystemSelectorContainer` (13-45)

</details>

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/helper.js (2)</summary><blockquote>

<details>
<summary>src/Components/TraceDiagram/SampleNodes.js (2)</summary>

* `marker` (41-46)
* `arrowStyle` (48-51)

</details>
<details>
<summary>src/Components/TraceDiagram/TraceDiagram.jsx (2)</summary>

* `edges` (23-23)
* `nodes` (22-22)

</details>

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/TraceDiagram.jsx (2)</summary><blockquote>

<details>
<summary>src/Components/TraceDiagram/helper.js (4)</summary>

* `nodes` (24-24)
* `edges` (23-23)
* `getNodesFromTrace` (22-59)
* `getNodesFromTrace` (22-59)

</details>
<details>
<summary>src/Components/TraceDiagram/DagreLayout.js (2)</summary>

* `getLayoutedElements` (4-33)
* `getLayoutedElements` (4-33)

</details>

</blockquote></details>
<details>
<summary>src/Viewer/FileViewer/FileViewer.js (1)</summary><blockquote>

<details>
<summary>src/Components/TraceDiagram/TraceDiagram.jsx (2)</summary>

* `TraceDiagram` (93-105)
* `TraceDiagram` (93-105)

</details>

</blockquote></details>
<details>
<summary>src/Providers/ASPProviders.js (2)</summary><blockquote>

<details>
<summary>src/Providers/FileTreeContext.js (1)</summary>

* `FileTreeContext` (5-5)

</details>
<details>
<summary>src/Providers/SystemsContext.js (1)</summary>

* `SystemsContext` (4-4)

</details>

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js (2)</summary><blockquote>

<details>
<summary>src/Providers/SystemsContext.js (1)</summary>

* `SystemsContext` (4-4)

</details>
<details>
<summary>src/Providers/ASPProviders.js (2)</summary>

* `loadSystems` (66-72)
* `systemsList` (27-27)

</details>

</blockquote></details>
<details>
<summary>src/Components/TraceDiagram/SampleNodes.js (1)</summary><blockquote>

<details>
<summary>src/Components/TraceDiagram/helper.js (2)</summary>

* `marker` (3-8)
* `arrowStyle` (10-13)

</details>

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js (1)</summary><blockquote>

<details>
<summary>src/Viewer/SideContainer/SideContainer.js (3)</summary>

* `handleMouseDown` (25-32)
* `handleMouseMove` (34-43)
* `handleMouseUp` (45-51)

</details>

</blockquote></details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelectorContainer.js (3)</summary><blockquote>

<details>
<summary>src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js (1)</summary>

* `SystemSelector` (11-114)

</details>
<details>
<summary>src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js (1)</summary>

* `VerticleHandle` (17-66)

</details>
<details>
<summary>src/Components/SystemSelectorContainer/TraceView/TraceView.js (1)</summary>

* `TraceView` (9-13)

</details>

</blockquote></details>

</details><details>
<summary>🪛 ESLint</summary>

<details>
<summary>src/Components/TraceDiagram/index.js</summary>

[error] 1-1: Missing semicolon.

(semi)

</details>
<details>
<summary>src/Components/TraceDiagram/SampleNodes.js</summary>

[error] 46-47: Missing semicolon.

(semi)

---

[error] 51-52: Missing semicolon.

(semi)

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (17)</summary><blockquote>

<details>
<summary>package.json (1)</summary>

`24-26`: **LGTM! Dependencies added for trace diagram visualization**

The addition of `@dagrejs/dagre` and `@xyflow/react` packages is appropriate for implementing the trace diagram visualization feature mentioned in the PR objectives.

</details>
<details>
<summary>src/Viewer/FileViewer/systemtrace.json (1)</summary>

`1-63`: **LGTM! Sample trace data for visualization development**

This JSON file provides well-structured sample data for the trace diagram visualization feature. The structure includes execution IDs, program names, timestamps, and relationships between components, which will be useful for testing the system trace visualization.

</details>
<details>
<summary>src/Viewer/SideContainer/SideContainer.js (2)</summary>

`3-4`: **LGTM: Component import added correctly**

The SystemSelectorContainer import is correctly added to integrate the new system selection functionality.

---

`55-55`: **LGTM: SystemSelectorContainer integration**

The SystemSelectorContainer is properly integrated into the SideContainer component when activeMenu is 1.

</details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelectorContainer.scss (1)</summary>

`10-14`: **LGTM! The title styling looks good.**

The styling for the title text is appropriate with a subtle gray color and consistent sizing.

</details>
<details>
<summary>src/Providers/ASPProviders.js (3)</summary>

`7-8`: **LGTM! Appropriate imports for the new functionality.**

These imports correctly bring in the necessary modules for implementing the system selection features.

---

`51-53`: **LGTM! Appropriate GET_SYSTEMS query message.**

The WebSocket message format is appropriate for requesting systems data from the server.

---

`83-85`: **LGTM! Appropriate context provider implementation.**

The SystemsContext provider is correctly implemented to make the systems list available to all child components.

</details>
<details>
<summary>src/Viewer/FileViewer/FileViewer.js (2)</summary>

`3-4`: **LGTM!**

Good job importing the new TraceDiagram component and the sample trace data that will be used for visualization.

---

`12-17`: **FileViewer implementation looks good**

The component has been successfully refactored from a complex implementation with multiple Monaco editors to a simpler one that renders the TraceDiagram component. This aligns with the PR objective to introduce a trace visualization feature.

</details>
<details>
<summary>src/Components/TraceDiagram/TraceDiagram.jsx (2)</summary>

`1-18`: **LGTM!**

The imports look appropriate for the functionality being implemented. Good job importing the required components from @xyflow/react, as well as the custom utility functions for layout and node generation.

---

`61-86`: **LGTM!**

The ReactFlow component is well-configured with appropriate props and child components. The panel positioning and controls provide good user interaction options.

</details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelectorContainer.js (1)</summary>

`1-7`: **LGTM!**

Good job importing the necessary components for system selection, trace view, and the vertical handle for resizing.

</details>
<details>
<summary>src/Components/TraceDiagram/SampleNodes.js (3)</summary>

`1-9`: **LGTM!**

Good job importing the necessary components from @xyflow/react and setting up the node defaults with appropriate source and target positions.

---

`11-39`: **Node configuration looks good**

The node configuration is well-structured with appropriate positioning and labels. Good job setting up a clear flow structure for the trace visualization.

---

`53-89`: **LGTM - Edge configurations look good**

The edge configurations are well-structured, showing clear flow connections between the nodes with appropriate styling and animations. The commented labels provide useful context for future enhancements.

</details>
<details>
<summary>src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js (1)</summary>

`74-78`: _🛠️ Refactor suggestion_

**Add systemsList to useEffect dependency array**

The `systemsList` variable is used inside the useEffect hook but is not included in the dependency array. This could lead to stale closures and unexpected behavior.

```diff
    useEffect(() => {
        if (systemsList) {
            loadSystems();
        }
-    }, [systemsList]);
+    }, [systemsList]); // No change needed as systemsList is already in the dependency array
```

Note: In this case, the dependency is already correctly included, but it's important to ensure that all variables used inside the effect are listed in the dependency array.



> Likely an incorrect or invalid review comment.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-25T05:24:44Z
user: login: vishalpalaniappan
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-25T05:30:36Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-25T05:31:02Z
user: login: vishalpalaniappan
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-25T05:33:13Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-25T05:33:38Z

Review comments:
diff_hunk: @@ -0,0 +1,59 @@
+import {MarkerType} from "@xyflow/react";
+
+const marker = {
+    type: MarkerType.ArrowClosed,
+    width: 20,
+    height: 20,
+    color: "#FF0072",
+};
+
+const arrowStyle = {
+    strokeWidth: 2,
+    stroke: "#FF0072",
+};
+
+/**
+ * Returns react flow nodes and edges from the given trace.
+ * @param {Object} trace
+ * @returns {Array} An array co
+ */
+
+
+export const getNodesFromTrace = (trace) => {
+    const edges = [];
+    const nodes = [];
+
+    trace.forEach((node, index) => {
+        node.flowId = String(index) + node.adliExecutionId;
+        const flowNode = {
+            id: node.flowId,
+            position: {x: 250, y: index * 200},
+            data: {label: node.programName},
+        };
+        flowNode.sourceNode = node;
+
+        if (index == 0) {
+            flowNode.type = "input";
+        }
+
+        if (index > 0) {
+            const prevNode = trace[index - 1];
+            const edge = {
+                id: prevNode.flowId + "-" + node.flowId,
+                source: prevNode.flowId,
+                target: node.flowId,
+                animated: true,
+                markerEnd: marker,
+                style: arrowStyle,
+            };
+            edges.push(edge);
+        }
+
+        nodes.push(flowNode);
+    });
+
+    return {
+        nodes: nodes,
+        edges: edges,
+    };
+};
path: src/Components/TraceDiagram/helper.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add input validation and consider more flexible node positioning**

The function lacks validation for the input trace array and uses hardcoded positioning that may not be optimal for all diagrams. Consider:

1. Adding input validation to handle empty arrays or invalid trace data
2. Making the horizontal position (x value) configurable or calculated based on the diagram's needs
3. Using a layout engine (like dagre) instead of manual positioning for complex diagrams

```diff
 export const getNodesFromTrace = (trace) => {
     const edges = [];
     const nodes = [];
+    
+    // Validate input
+    if (!Array.isArray(trace) || trace.length === 0) {
+        return { nodes, edges };
+    }

     trace.forEach((node, index) => {
         node.flowId = String(index) + node.adliExecutionId;
         const flowNode = {
             id: node.flowId,
-            position: {x: 250, y: index * 200},
+            position: {x: 250, y: index * 200}, // Consider making x position configurable
             data: {label: node.programName},
         };
         flowNode.sourceNode = node;
```



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
export const getNodesFromTrace = (trace) => {
    const edges = [];
    const nodes = [];

    // Validate input
    if (!Array.isArray(trace) || trace.length === 0) {
        return { nodes, edges };
    }

    trace.forEach((node, index) => {
        node.flowId = String(index) + node.adliExecutionId;
        const flowNode = {
            id: node.flowId,
            position: {x: 250, y: index * 200}, // Consider making x position configurable
            data: {label: node.programName},
        };
        flowNode.sourceNode = node;

        if (index == 0) {
            flowNode.type = "input";
        }

        if (index > 0) {
            const prevNode = trace[index - 1];
            const edge = {
                id: prevNode.flowId + "-" + node.flowId,
                source: prevNode.flowId,
                target: node.flowId,
                animated: true,
                markerEnd: marker,
                style: arrowStyle,
            };
            edges.push(edge);
        }

        nodes.push(flowNode);
    });

    return {
        nodes: nodes,
        edges: edges,
    };
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:42Z
author_association: NONE
diff_hunk: @@ -0,0 +1,21 @@
+
+/**
+ * This class contains all the properties of a system.
+ */
+class System {
+    /**
+     * @param {Object} systemInfo Information about the loaded system.
+     * @param {Function} sendJsonMessage Function to send websocket message.
+     */
+    constructor (systemInfo, sendJsonMessage) {
+        this.id = systemInfo.system_id + "_" + systemInfo.version;
+        this.sysId = String(systemInfo.system_id);
+        this.version = String(systemInfo.version);
+        this.programs = systemInfo.programs;
+        this.deployments = systemInfo.deployments;
+
+        console.log("Created System:", this.sysId, this.version);
+    }
path: src/Providers/System.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Unused parameter and missing validation**

The constructor accepts `sendJsonMessage` as a parameter but never uses it. Additionally, there's no validation to ensure the `systemInfo` parameter contains the required properties before accessing them.


```diff
constructor (systemInfo, sendJsonMessage) {
+    // Validate required properties
+    if (!systemInfo || !systemInfo.system_id || !systemInfo.version) {
+        throw new Error('systemInfo is missing required properties');
+    }
    this.id = systemInfo.system_id + "_" + systemInfo.version;
    this.sysId = String(systemInfo.system_id);
    this.version = String(systemInfo.version);
    this.programs = systemInfo.programs;
    this.deployments = systemInfo.deployments;

    console.log("Created System:", this.sysId, this.version);
}
```

If `sendJsonMessage` is intended for future use, consider adding a TODO comment explaining its purpose.


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
// File: src/Providers/System.js
constructor (systemInfo, sendJsonMessage) {
    // Validate required properties
    if (!systemInfo || !systemInfo.system_id || !systemInfo.version) {
        throw new Error('systemInfo is missing required properties');
    }

    this.id = systemInfo.system_id + "_" + systemInfo.version;
    this.sysId = String(systemInfo.system_id);
    this.version = String(systemInfo.version);
    this.programs = systemInfo.programs;
    this.deployments = systemInfo.deployments;

    console.log("Created System:", this.sysId, this.version);
    // TODO: explain intended use of sendJsonMessage or remove it if unused
}
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,27 @@
+.systemContainer {
+    color:white;
+    font-size:13px;
+    padding:0 10px;
+    width: 100%;
+    height: 100%;
+    overflow-y: auto;
+    scrollbar-gutter: stable;
+    scrollbar-color: #47474766 #252526;
+    scrollbar-width: thin;
+}
+
+.systemSelectRow {
+    margin: 5px 0;
+}
+
+.customSelector {
+    border: none;
+    background: #252526;
+    color: white;
+    border-bottom: solid 1px rgb(77, 77, 77);
+    width: 100%;
+}
+
+.customSelector:focus {
+    outline: none;
+}
path: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add alternative focus styling for accessibility.**

Removing the outline without providing an alternative focus indicator reduces accessibility for keyboard users. Consider adding a different visual indication when the selector is focused.

```diff
.customSelector:focus {
    outline: none;
+    box-shadow: 0 0 0 2px rgba(100, 180, 255, 0.7);
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
.customSelector:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(100, 180, 255, 0.7);
}
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,109 @@
+import React, {useCallback, useEffect, useState} from "react";
+
+import {
+    Controls,
+    Panel,
+    ReactFlow,
+    ReactFlowProvider,
+    useEdgesState,
+    useNodesState,
+    useReactFlow
+} from "@xyflow/react";
+import PropTypes from "prop-types";
+
+import {getLayoutedElements} from "./DagreLayout.js";
+import {getNodesFromTrace} from "./helper.js";
+
+import "@xyflow/react/dist/style.css";
+
+const Flow = ({trace}) => {
+    const {fitView} = useReactFlow();
+    const [colorMode, setColorMode] = useState("dark");
+    const [nodes, setNodes, onNodesChange] = useNodesState([]);
+    const [edges, setEdges, onEdgesChange] = useEdgesState([]);
+
+    const onChange = (evt) =>
+        setColorMode(evt.target.value);
+
+    const onLayout = useCallback(
+        (direction) => {
+            const layouted = getLayoutedElements(nodes, edges, {direction});
+
+            setNodes([...layouted.nodes]);
+            setEdges([...layouted.edges]);
+
+            fitView();
+        },
+        [nodes, edges]
+    );
+
+    useEffect(() => {
+        if (trace) {
+            const flowInfo = getNodesFromTrace(trace);
+
+            const layouted = getLayoutedElements(
+                flowInfo.nodes,
+                flowInfo.edges,
+                {direction: "TB"}
+            );
+
+            setNodes([...layouted.nodes]);
+            setEdges([...layouted.edges]);
+
+            fitView();
+        }
+    }, [trace]);
path: src/Components/TraceDiagram/TraceDiagram.jsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add error handling for trace data processing**

The useEffect hook that processes trace data lacks error handling for malformed input or processing failures.

Add try-catch block to handle potential errors:

```diff
useEffect(() => {
    if (trace) {
+       try {
            const flowInfo = getNodesFromTrace(trace);

            const layouted = getLayoutedElements(
                flowInfo.nodes,
                flowInfo.edges,
                {direction: "TB"}
            );

            setNodes([...layouted.nodes]);
            setEdges([...layouted.edges]);

            fitView();
+       } catch (err) {
+           console.error("Failed to process trace data:", err);
+           setError("Failed to process trace data. Please check the format.");
+       }
    }
}, [trace]);
```


> Committable suggestion skipped: line range outside the PR's diff.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,109 @@
+import React, {useCallback, useEffect, useState} from "react";
+
+import {
+    Controls,
+    Panel,
+    ReactFlow,
+    ReactFlowProvider,
+    useEdgesState,
+    useNodesState,
+    useReactFlow
+} from "@xyflow/react";
+import PropTypes from "prop-types";
+
+import {getLayoutedElements} from "./DagreLayout.js";
+import {getNodesFromTrace} from "./helper.js";
+
+import "@xyflow/react/dist/style.css";
+
+const Flow = ({trace}) => {
+    const {fitView} = useReactFlow();
+    const [colorMode, setColorMode] = useState("dark");
+    const [nodes, setNodes, onNodesChange] = useNodesState([]);
+    const [edges, setEdges, onEdgesChange] = useEdgesState([]);
+
+    const onChange = (evt) =>
+        setColorMode(evt.target.value);
+
+    const onLayout = useCallback(
+        (direction) => {
+            const layouted = getLayoutedElements(nodes, edges, {direction});
+
+            setNodes([...layouted.nodes]);
+            setEdges([...layouted.edges]);
+
+            fitView();
+        },
+        [nodes, edges]
+    );
+
path: src/Components/TraceDiagram/TraceDiagram.jsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add error handling for missing trace or layout data**

The Flow component is missing error handling for cases where trace data might be malformed or layout application fails.

Consider adding error states and error boundaries:

```diff
const Flow = ({trace}) => {
    const {fitView} = useReactFlow();
    const [colorMode, setColorMode] = useState("dark");
    const [nodes, setNodes, onNodesChange] = useNodesState([]);
    const [edges, setEdges, onEdgesChange] = useEdgesState([]);
+   const [error, setError] = useState(null);

    const onChange = (evt) =>
        setColorMode(evt.target.value);

    const onLayout = useCallback(
        (direction) => {
+           try {
                const layouted = getLayoutedElements(nodes, edges, {direction});

                setNodes([...layouted.nodes]);
                setEdges([...layouted.edges]);

                fitView();
+           } catch (err) {
+               console.error("Failed to apply layout:", err);
+               setError("Failed to apply layout. Please try again.");
+           }
        },
        [nodes, edges]
    );
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
const Flow = ({trace}) => {
    const {fitView} = useReactFlow();
    const [colorMode, setColorMode] = useState("dark");
    const [nodes, setNodes, onNodesChange] = useNodesState([]);
    const [edges, setEdges, onEdgesChange] = useEdgesState([]);
    const [error, setError] = useState(null);

    const onChange = (evt) =>
        setColorMode(evt.target.value);

    const onLayout = useCallback(
        (direction) => {
            try {
                const layouted = getLayoutedElements(nodes, edges, {direction});

                setNodes([...layouted.nodes]);
                setEdges([...layouted.edges]);

                fitView();
            } catch (err) {
                console.error("Failed to apply layout:", err);
                setError("Failed to apply layout. Please try again.");
            }
        },
        [nodes, edges]
    );

    // ...rest of the component
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,114 @@
+import React, {useContext, useEffect, useState} from "react";
+
+import SystemsContext from "../../../Providers/SystemsContext";
+
+import "./SystemSelector.scss";
+
+/**
+ * Contains the system selector components.
+ * @return {JSX.Element}
+ */
+export function SystemSelector () {
+    const {systemsList} = useContext(SystemsContext);
+
+    const [systems, setSystems] = useState([]);
+    const [versions, setVersions] = useState([]);
+    const [deployments, setDeployments] = useState([]);
+    const [activeSystemId, setActiveSystemId] = useState();
+    const [activeVersion, setActiveVersion] = useState();
+    const [activeDeployment, setActiveDeployment] = useState();
+
+    // Load system select dropdown from systemsList and set active system.
+    const loadSystems = () => {
+        const sysIds = [...new Set(systemsList.map((item) => item.sysId))];
+        const _systems = [];
+        sysIds.forEach((id, index) => {
+            _systems.push(<option key={id} value={id}>{id}</option>);
+        });
+        setSystems(_systems);
+        loadVersions(sysIds[0]);
+    };
+
+    // Given a system ID, load versions into select dropdown, set active version
+    const loadVersions = (systemid) => {
+        setActiveSystemId(systemid);
+        const filteredSystems = systemsList.filter((obj) => {return obj.sysId === systemid;});
+        const versionsList = [...new Set(filteredSystems.map((item) => item.version))];
+        const _versions = [];
+        versionsList.forEach((version, index) => {
+            _versions.push(<option key={version} value={version}>{version}</option>);
+        });
+        setVersions(_versions);
+        loadDeployments(systemid, versionsList[0]);
+    };
+
+    // Given a system id and version load deployments and set active deployment.
+    const loadDeployments = (systemid, version) => {
+        setActiveVersion(version);
+        const system = systemsList.filter(
+            (obj) => {return (obj.sysId === systemid && obj.version == version);}
+        )[0];
+        const _deployments = [];
+        system.deployments.forEach((deployment, index) => {
+            const id = deployment.deployment_id;
+            _deployments.push(<option key={id} value={id}>{id}</option>);
+        });
+        setDeployments(_deployments);
+        setActiveDeployment(system.deployments[0].deployment_id);
path: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add defensive checks for deployments array**

The code assumes that `system.deployments` always exists and is an array. You should add defensive checks to prevent potential runtime errors.

```diff
-        system.deployments.forEach((deployment, index) => {
-            const id = deployment.deployment_id;
-            _deployments.push(<option key={id} value={id}>{id}</option>);
-        });
-        setDeployments(_deployments);
-        setActiveDeployment(system.deployments[0].deployment_id);
+        if (system && system.deployments && Array.isArray(system.deployments) && system.deployments.length > 0) {
+            system.deployments.forEach((deployment, index) => {
+                const id = deployment.deployment_id;
+                _deployments.push(<option key={id} value={id}>{id}</option>);
+            });
+            setDeployments(_deployments);
+            setActiveDeployment(system.deployments[0].deployment_id);
+        } else {
+            setDeployments([]);
+            setActiveDeployment(null);
+        }
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
        if (system && system.deployments && Array.isArray(system.deployments) && system.deployments.length > 0) {
            system.deployments.forEach((deployment, index) => {
                const id = deployment.deployment_id;
                _deployments.push(<option key={id} value={id}>{id}</option>);
            });
            setDeployments(_deployments);
            setActiveDeployment(system.deployments[0].deployment_id);
        } else {
            setDeployments([]);
            setActiveDeployment(null);
        }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,114 @@
+import React, {useContext, useEffect, useState} from "react";
+
+import SystemsContext from "../../../Providers/SystemsContext";
+
+import "./SystemSelector.scss";
+
+/**
+ * Contains the system selector components.
+ * @return {JSX.Element}
+ */
+export function SystemSelector () {
+    const {systemsList} = useContext(SystemsContext);
+
+    const [systems, setSystems] = useState([]);
+    const [versions, setVersions] = useState([]);
+    const [deployments, setDeployments] = useState([]);
+    const [activeSystemId, setActiveSystemId] = useState();
+    const [activeVersion, setActiveVersion] = useState();
+    const [activeDeployment, setActiveDeployment] = useState();
+
+    // Load system select dropdown from systemsList and set active system.
+    const loadSystems = () => {
+        const sysIds = [...new Set(systemsList.map((item) => item.sysId))];
+        const _systems = [];
+        sysIds.forEach((id, index) => {
+            _systems.push(<option key={id} value={id}>{id}</option>);
+        });
+        setSystems(_systems);
+        loadVersions(sysIds[0]);
+    };
path: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add error handling for empty or malformed systemsList**

The `loadSystems` function assumes that `systemsList` is a non-empty array. You should add error handling to handle cases where `systemsList` is empty or malformed.

```diff
    const loadSystems = () => {
+       if (!systemsList || !Array.isArray(systemsList) || systemsList.length === 0) {
+           setSystems([]);
+           setVersions([]);
+           setDeployments([]);
+           return;
+       }
        const sysIds = [...new Set(systemsList.map((item) => item.sysId))];
        const _systems = [];
        sysIds.forEach((id, index) => {
            _systems.push(<option key={id} value={id}>{id}</option>);
        });
        setSystems(_systems);
+       if (sysIds.length > 0) {
            loadVersions(sysIds[0]);
+       }
    };
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
    const loadSystems = () => {
        if (!systemsList || !Array.isArray(systemsList) || systemsList.length === 0) {
            setSystems([]);
            setVersions([]);
            setDeployments([]);
            return;
        }
        const sysIds = [...new Set(systemsList.map((item) => item.sysId))];
        const _systems = [];
        sysIds.forEach((id, index) => {
            _systems.push(<option key={id} value={id}>{id}</option>);
        });
        setSystems(_systems);
        if (sysIds.length > 0) {
            loadVersions(sysIds[0]);
        }
    };
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,66 @@
+import React, {useRef} from "react";
+
+import PropTypes from "prop-types";
+
+import "./VerticleHandle.scss";
+
+VerticleHandle.propTypes = {
+    topDiv: PropTypes.object,
+    bottomDiv: PropTypes.object,
+};
+
+/**
+ * Renders a vertically resizable handle for the accordian components.
+ * It accepts two components which are resized when the handle is moved.
+ * @return {JSX.Element}
+ */
+export function VerticleHandle ({topDiv, bottomDiv}) {
+    const handleRef = useRef();
+
+    const MIN_CONTAINER_HEIGHT = 25;
+
+    // Initial values used to calculate delta on mouse move.
+    let downValueY;
+    let topHeight;
+    let bottomHeight;
+
+    const handleMouseDown = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+
+        document.addEventListener("mousemove", handleMouseMove);
+        document.addEventListener("mouseup", handleMouseUp);
+
+        downValueY = e.clientY;
+        topHeight = topDiv.current.getBoundingClientRect().height;
+        bottomHeight = bottomDiv.current.getBoundingClientRect().height;
+
+        handleRef.current.classList.add("handle-active");
+    };
+
+    const handleMouseMove = (e) => {
+        e.preventDefault();
+        e.stopPropagation();
+
+        const delta = e.clientY - downValueY;
+        const newPreHeight = topHeight + delta;
+        const newPostHeight = bottomHeight - delta;
+
+        if (newPreHeight > MIN_CONTAINER_HEIGHT && newPostHeight > MIN_CONTAINER_HEIGHT) {
+            topDiv.current.style.height = newPreHeight + "px";
+            bottomDiv.current.style.height = newPostHeight + "px";
+        }
path: src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add null checks before accessing current property of refs**

You should verify that the refs have valid current properties before attempting to access and modify them to prevent potential runtime errors.

```diff
-        if (newPreHeight > MIN_CONTAINER_HEIGHT && newPostHeight > MIN_CONTAINER_HEIGHT) {
-            topDiv.current.style.height = newPreHeight + "px";
-            bottomDiv.current.style.height = newPostHeight + "px";
+        if (newPreHeight > MIN_CONTAINER_HEIGHT && 
+            newPostHeight > MIN_CONTAINER_HEIGHT && 
+            topDiv && topDiv.current && 
+            bottomDiv && bottomDiv.current) {
+            topDiv.current.style.height = newPreHeight + "px";
+            bottomDiv.current.style.height = newPostHeight + "px";
        }
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
        if (newPreHeight > MIN_CONTAINER_HEIGHT &&
            newPostHeight > MIN_CONTAINER_HEIGHT &&
            topDiv && topDiv.current &&
            bottomDiv && bottomDiv.current) {
            topDiv.current.style.height = newPreHeight + "px";
            bottomDiv.current.style.height = newPostHeight + "px";
        }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,66 @@
+import React, {useRef} from "react";
+
+import PropTypes from "prop-types";
+
+import "./VerticleHandle.scss";
+
+VerticleHandle.propTypes = {
+    topDiv: PropTypes.object,
+    bottomDiv: PropTypes.object,
+};
+
+/**
+ * Renders a vertically resizable handle for the accordian components.
+ * It accepts two components which are resized when the handle is moved.
+ * @return {JSX.Element}
+ */
+export function VerticleHandle ({topDiv, bottomDiv}) {
+    const handleRef = useRef();
+
+    const MIN_CONTAINER_HEIGHT = 25;
+
+    // Initial values used to calculate delta on mouse move.
+    let downValueY;
+    let topHeight;
+    let bottomHeight;
path: src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Move variables inside event handlers or use React state/refs**

Variables defined at component scope will be recreated on each render, which can lead to unexpected behavior. These should be moved inside the event handlers or converted to state variables or refs.

```diff
-    // Initial values used to calculate delta on mouse move.
-    let downValueY;
-    let topHeight;
-    let bottomHeight;

    const handleMouseDown = (e) => {
        e.preventDefault();
        e.stopPropagation();

        document.addEventListener("mousemove", handleMouseMove);
        document.addEventListener("mouseup", handleMouseUp);

+        // Initial values used to calculate delta on mouse move
+        let downValueY = e.clientY;
+        let topHeight = topDiv.current.getBoundingClientRect().height;
+        let bottomHeight = bottomDiv.current.getBoundingClientRect().height;
-        downValueY = e.clientY;
-        topHeight = topDiv.current.getBoundingClientRect().height;
-        bottomHeight = bottomDiv.current.getBoundingClientRect().height;

        handleRef.current.classList.add("handle-active");
+        
+        // Define the handleMouseMove function inside handleMouseDown to capture the variables in closure
+        const handleMouseMove = (e) => {
+            e.preventDefault();
+            e.stopPropagation();
+
+            const delta = e.clientY - downValueY;
+            const newPreHeight = topHeight + delta;
+            const newPostHeight = bottomHeight - delta;
+
+            if (newPreHeight > MIN_CONTAINER_HEIGHT && newPostHeight > MIN_CONTAINER_HEIGHT) {
+                topDiv.current.style.height = newPreHeight + "px";
+                bottomDiv.current.style.height = newPostHeight + "px";
+            }
+        };
+        
+        // Define the handleMouseUp function inside handleMouseDown
+        const handleMouseUp = (e) => {
+            e.preventDefault();
+            e.stopPropagation();
+            document.removeEventListener("mousemove", handleMouseMove);
+            document.removeEventListener("mouseup", handleMouseUp);
+            handleRef.current.classList.remove("handle-active");
+        };
+        
+        // Add the event listeners with the locally defined functions
+        document.addEventListener("mousemove", handleMouseMove);
+        document.addEventListener("mouseup", handleMouseUp);
    };

-    const handleMouseMove = (e) => {
-        e.preventDefault();
-        e.stopPropagation();
-
-        const delta = e.clientY - downValueY;
-        const newPreHeight = topHeight + delta;
-        const newPostHeight = bottomHeight - delta;
-
-        if (newPreHeight > MIN_CONTAINER_HEIGHT && newPostHeight > MIN_CONTAINER_HEIGHT) {
-            topDiv.current.style.height = newPreHeight + "px";
-            bottomDiv.current.style.height = newPostHeight + "px";
-        }
-    };
-
-    const handleMouseUp = (e) => {
-        e.preventDefault();
-        e.stopPropagation();
-        document.removeEventListener("mousemove", handleMouseMove);
-        document.removeEventListener("mouseup", handleMouseUp);
-        handleRef.current.classList.remove("handle-active");
-    };
```


> Committable suggestion skipped: line range outside the PR's diff.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-25T05:24:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,21 @@
+
+/**
+ * This class contains all the properties of a system.
+ */
+class System {
+    /**
+     * @param {Object} systemInfo Information about the loaded system.
+     * @param {Function} sendJsonMessage Function to send websocket message.
+     */
+    constructor (systemInfo, sendJsonMessage) {
+        this.id = systemInfo.system_id + "_" + systemInfo.version;
+        this.sysId = String(systemInfo.system_id);
+        this.version = String(systemInfo.version);
+        this.programs = systemInfo.programs;
+        this.deployments = systemInfo.deployments;
+
+        console.log("Created System:", this.sysId, this.version);
+    }
path: src/Providers/System.js
user: login: vishalpalaniappan
body: My intention was to have the system class build queries and send the request to the server on its own. However, I don't think this will be necessary. Since the active system id, system version and deployment id are state variables in the system selector component, the query to access the system level traces can be built outside of class.

I have removed it in commit https://github.com/vishalpalaniappan/automated-system-viewer/pull/7/commits/63cfb1d6f3a85a601407fb00ffaf1275968f4459.

It is possible I might want to change this architecture as the number of queries increases. I will revisit it in a future PR.
created_at: 2025-04-25T05:30:36Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,21 @@
+
+/**
+ * This class contains all the properties of a system.
+ */
+class System {
+    /**
+     * @param {Object} systemInfo Information about the loaded system.
+     * @param {Function} sendJsonMessage Function to send websocket message.
+     */
+    constructor (systemInfo, sendJsonMessage) {
+        this.id = systemInfo.system_id + "_" + systemInfo.version;
+        this.sysId = String(systemInfo.system_id);
+        this.version = String(systemInfo.version);
+        this.programs = systemInfo.programs;
+        this.deployments = systemInfo.deployments;
+
+        console.log("Created System:", this.sysId, this.version);
+    }
path: src/Providers/System.js
user: login: coderabbitai[bot]
body: @vishalpalaniappan Thank you for explaining your design decision and for addressing the unused parameter issue. Your approach makes sense - keeping the query building logic in the component that maintains the state variables (system selector component) rather than in the System class itself. This separation of concerns is cleaner and more maintainable. Good job on the implementation!

(\_/) 
( •ᴗ•) 
/ >👍


<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@vishalpalaniappan Thank you for explaining your design decision and for addressing the unused parameter issue. Your approach makes sense - keeping the query building logic in the component that maintains the state variables (system selector component) rather than in the System class itself. This separation of concerns is cleaner and more maintainable. Good job on the implementation!

(\_/) 
( •ᴗ•) 
/ >👍</answer></rawResChunk> -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-04-25T05:31:02Z
author_association: NONE
diff_hunk: @@ -0,0 +1,27 @@
+.systemContainer {
+    color:white;
+    font-size:13px;
+    padding:0 10px;
+    width: 100%;
+    height: 100%;
+    overflow-y: auto;
+    scrollbar-gutter: stable;
+    scrollbar-color: #47474766 #252526;
+    scrollbar-width: thin;
+}
+
+.systemSelectRow {
+    margin: 5px 0;
+}
+
+.customSelector {
+    border: none;
+    background: #252526;
+    color: white;
+    border-bottom: solid 1px rgb(77, 77, 77);
+    width: 100%;
+}
+
+.customSelector:focus {
+    outline: none;
+}
path: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss
user: login: vishalpalaniappan
body: I have not designed the application to be more friendly for different accessibility needs yet. I will dedicate time to this when I formalize all the components in the component library.
created_at: 2025-04-25T05:33:13Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,27 @@
+.systemContainer {
+    color:white;
+    font-size:13px;
+    padding:0 10px;
+    width: 100%;
+    height: 100%;
+    overflow-y: auto;
+    scrollbar-gutter: stable;
+    scrollbar-color: #47474766 #252526;
+    scrollbar-width: thin;
+}
+
+.systemSelectRow {
+    margin: 5px 0;
+}
+
+.customSelector {
+    border: none;
+    background: #252526;
+    color: white;
+    border-bottom: solid 1px rgb(77, 77, 77);
+    width: 100%;
+}
+
+.customSelector:focus {
+    outline: none;
+}
path: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss
user: login: coderabbitai[bot]
body: @vishalpalaniappan I understand your approach. Addressing accessibility comprehensively when formalizing your component library is a solid plan. This will allow you to implement consistent accessibility patterns across all components rather than making isolated fixes. Let me know if you'd like any resources on accessibility best practices when you're ready to tackle that phase of development.



🐰✏️

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: vishalpalaniappan
PR: vishalpalaniappan/automated-system-viewer#7
File: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss:25-27
Timestamp: 2025-04-25T05:33:37.075Z
Learning: Accessibility improvements for the application are planned for a later phase when components are formalized in a component library, rather than implementing one-off fixes during development.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>




<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@vishalpalaniappan I understand your approach. Addressing accessibility comprehensively when formalizing your component library is a solid plan. This will allow you to implement consistent accessibility patterns across all components rather than making isolated fixes. Let me know if you'd like any resources on accessibility best practices when you're ready to tackle that phase of development.



🐰✏️

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: vishalpalaniappan
PR: vishalpalaniappan/automated-system-viewer#7
File: src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.scss:25-27
Timestamp: 2025-04-25T05:33:37.075Z
Learning: Accessibility improvements for the application are planned for a later phase when components are formalized in a component library, rather than implementing one-off fixes during development.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>

</answer></rawResChunk> -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-04-25T05:33:38Z
author_association: NONE

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-04-24T06:15:25Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: review paused by coderabbit.ai -->

> [!NOTE]
> ## Reviews paused
> 
> Use the following commands to manage reviews:
> - `@coderabbitai resume` to resume automatic reviews.
> - `@coderabbitai review` to trigger a single review.

<!-- end of auto-generated comment: review paused by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This update introduces a new system selection and trace visualization interface. It adds a modular System Selector UI with cascading dropdowns for system, version, and deployment selection, managed via a new SystemsContext and System class. The trace diagram visualization is implemented using the @xyflow/react library, with helper utilities for layout and sample data. The FileViewer component is refactored to display the trace diagram instead of multiple code editors. Supporting SCSS stylesheets are added for new components. The package dependencies are updated to include dagre and xyflow, while removing unused libraries.

## Changes

| File(s)                                                                                   | Change Summary |
|------------------------------------------------------------------------------------------|---------------|
| `package.json`                                                                           | Added `@dagrejs/dagre` and `@xyflow/react` dependencies; removed `clp-ffi-js` and `react-grid-layout`. |
| `src/Components/SystemSelectorContainer/SystemSelector/SystemSelector.js`,<br>`SystemSelector.scss` | Added new SystemSelector React component with cascading dropdowns and its styles. |
| `src/Components/SystemSelectorContainer/SystemSelectorContainer.js`,<br>`SystemSelectorContainer.scss` | Added SystemSelectorContainer component for layout and its styles. |
| `src/Components/SystemSelectorContainer/TraceView/TraceView.js`,<br>`TraceView.scss`     | Added TraceView placeholder component and styles. |
| `src/Components/SystemSelectorContainer/VerticleHandle/VerticleHandle.js`,<br>`VerticleHandle.scss` | Added VerticleHandle draggable divider component and its styles. |
| `src/Components/TraceDiagram/DagreLayout.js`                                             | Added Dagre-based utility for laying out graph nodes and edges. |
| `src/Components/TraceDiagram/SampleNodes.js`                                             | Added sample nodes and edges for trace diagrams. |
| `src/Components/TraceDiagram/TraceDiagram.jsx`,<br>`helper.js`,<br>`index.js`            | Added TraceDiagram React component, helper for building nodes/edges from traces, and index file. |
| `src/Providers/ASPProviders.js`                                                          | Refactored to manage systems list state/context, update WebSocket message handling, and instantiate System objects. |
| `src/Providers/System.js`                                                                | Added new System class for encapsulating system info. |
| `src/Providers/SystemsContext.js`                                                        | Renamed UniqueTraceContext to SystemsContext. |
| `src/Viewer/FileViewer/FileViewer.js`                                                    | Refactored to remove grid layout and Monaco editors, now renders TraceDiagram with static data. |
| `src/Viewer/FileViewer/systemtrace.json`                                                 | Added sample trace data as JSON. |
| `src/Viewer/SideContainer/SideContainer.js`                                              | Imports and renders SystemSelectorContainer, doubles accordion width. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant SystemSelector
    participant SystemsContext
    participant SystemSelectorContainer
    participant TraceView
    participant TraceDiagram

    User->>SystemSelector: Select system/version/deployment
    SystemSelector->>SystemsContext: Read systemsList
    SystemSelector->>SystemSelector: Update dropdowns and state
    SystemSelectorContainer->>SystemSelector: Render system selection UI
    SystemSelectorContainer->>VerticleHandle: Enable vertical resizing
    SystemSelectorContainer->>TraceView: Render traces section
    TraceView->>TraceDiagram: (future) Pass trace data for visualization
    TraceDiagram->>@xyflow/react: Render flow diagram
```

## Possibly related PRs

- **#5:** Refactored `ASPProviders.js` to replace unique trace and file tree state with systems list state/context, directly related to the new systems management in this PR.
- **#4:** Modified WebSocket message handling in `ASPProviders.js`, relevant as this PR also changes WebSocket protocol and message processing.
- **#2:** Removed `react-grid-layout` and refactored `FileViewer` to not use it, directly opposing the previous addition of grid layout and Monaco editors.

## Poem

> Hopping through systems, I pick and I choose,  
> With dropdowns that cascade, there’s nothing to lose!  
> Traces now flow in diagrams bright,  
> As nodes and edges dance in delight.  
> Out with the old grid, in with the new,  
> This rabbit’s excited for all we can do!  
> 🐇✨

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=vishalpalaniappan/automated-system-viewer&utm_content=7):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: vishalpalaniappan
created_at: 2025-04-25T05:21:17Z
body: @coderabbitai review
author_association: OWNER
user: login: coderabbitai[bot]
created_at: 2025-04-25T05:21:22Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
<details>
<summary>✅ Actions performed</summary>

Review triggered.

> Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

</details>
author_association: NONE
user: login: vishalpalaniappan
created_at: 2025-04-25T05:26:52Z
body: @coderabbitai pause
author_association: OWNER
user: login: coderabbitai[bot]
created_at: 2025-04-25T05:28:00Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
<details>
<summary>✅ Actions performed</summary>

Reviews paused.

</details>
author_association: NONE