import React, { useState } from "react"; import clsx from "clsx"; import { connect } from "react-redux"; import { getEdges } from "./redux/store"; import { setFindNode } from "./redux/findNode"; import { setLinks } from "./redux/links"; import { setGraphData } from "./redux/graphData"; import { setSelectedPath } from "./redux/graphPaths"; import { AutoSizer, Column, Table } from "react-virtualized"; import TableCell from "@material-ui/core/TableCell"; import Typography from "@material-ui/core/Typography"; import Tooltip from '@material-ui/core/Tooltip'; import GraphPaths from "./GraphPaths"; import { makeStyles, withStyles } from "@material-ui/core/styles"; import LoadingBar from "./LoadingBar"; import TextField from "@material-ui/core/TextField"; import { List, ListItemText, Paper, Button } from "@material-ui/core"; const columns = [ { dataKey: "type", label: "Type", width: 30 }, { dataKey: "source", label: "From", width: 180 }, { dataKey: "to", label: "➔", width: 40 }, { dataKey: "target", label: "To", width: 180 }, ]; const visibilityTypes = ['Global', 'Public', 'Private', 'Interface']; function componentToHex(c) { var hex = c.toString(16); return hex.length == 1 ? "0" + hex : hex; } function rgbToHex(r, g, b) { return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); } function hexToRgb(hex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, function (m, r, g, b) { return r + r + g + g + b + b; }); var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16), } : null; } function incrementPallete(palleteColor, increment) { var rgb = hexToRgb(palleteColor); rgb.r += increment; rgb.g += increment; rgb.b += increment; return rgbToHex(rgb.r, rgb.g, rgb.b); } const styles = (theme) => ({ flexContainer: { display: "flex", alignItems: "center", }, table: { // temporary right-to-left patch, waiting for // https://github.com/bvaughn/react-virtualized/issues/454 "& .ReactVirtualized__Table__headerRow": { flip: false, paddingRight: theme.direction === "rtl" ? "0 !important" : undefined, }, }, tableRowOdd: { backgroundColor: incrementPallete(theme.palette.grey[800], 10), }, tableRowEven: { backgroundColor: theme.palette.grey[800], }, tableRowHover: { "&:hover": { backgroundColor: theme.palette.grey[600], }, }, tableCell: { flex: 1, }, noClick: { cursor: "initial", }, }); const EdgeList = ({ selectedGraph, links, setLinks, linksTrans, loading, setFindNode, classes, setTransPath }) => { const [searchTerm, setSearchTerm] = useState(''); const selectedLinks = links.filter(link => link.selected); function searchedLinks() { if (searchTerm == '') { return links; } return links.filter(link => { if (link.source.name && link.target.name) { return link.source.name.indexOf(searchTerm) > -1 || link.target.name.indexOf(searchTerm) > -1; }}); } function handleRowClick(event) { setLinks( links.map((temp_link, index) => { if (index == searchedLinks()[event.index].index) { temp_link.selected = !temp_link.selected; } else { temp_link.selected = false; } return temp_link; }) ); setTransPath(event, '', ''); } function handleSearchTermChange(event) { setSearchTerm(event.target.value); } function reduceNodeName(node) { if (node.name) { return node.name; } return node.substring(node.lastIndexOf('/') + 1); } const getRowClassName = ({ index }) => { return clsx( index % 2 == 0 ? styles.tableRowEven : classes.tableRowOdd, classes.flexContainer, { [classes.tableRowHover]: index !== -1, } ); }; const cellRenderer = ({ cellData, columnIndex, rowIndex }) => { return ( { columnIndex == 0 ? ( searchedLinks()[rowIndex].data?.direct ? D : T ) : "" } { columnIndex == 1 ? reduceNodeName(searchedLinks()[rowIndex].source) : "" } { columnIndex == 2 ? (searchedLinks()[rowIndex].selected ? ➔ : "➔") : "" } { columnIndex == 3 ? reduceNodeName(searchedLinks()[rowIndex].target) : "" } ); }; const headerRenderer = ({ label, columnIndex }) => { return ( {label} ); }; return ( event.target.select()} label="Search for Edge" /> {({ height, width }) => ( searchedLinks()[index].target} rowHeight={25} onRowClick={handleRowClick} gridStyle={{ direction: "inherit", }} size={"small"} rowClassName={getRowClassName} headerHeight={35} > {columns.map(({ dataKey, ...other }, index) => { return ( headerRenderer({ ...headerProps, columnIndex: index, }) } cellRenderer={cellRenderer} dataKey={dataKey} {...other} /> ); })} )} { selectedLinks[0]?.source.name } ➔ { selectedLinks[0]?.target.name } Type: { selectedLinks[0]?.data.direct ? "Direct" : "Transitive" } }/> Visibility: { visibilityTypes[selectedLinks[0]?.data.visibility] } }/> Source: { selectedLinks[0]?.source.id } } secondary= { selectedLinks[0]?.source.type }/> Target: { selectedLinks[0]?.target.id } } secondary= { selectedLinks[0]?.target.type }/> Symbol Dependencies: { selectedLinks[0]?.data.symbols.length } }/> { selectedLinks[0]?.data.symbols.map((symbol, index) => { return ( ); }) } setTransPath(event, selectedLinks[0]?.source.id, selectedLinks[0]?.target.id) }>View Paths ); }; export default connect(getEdges, { setGraphData, setFindNode, setLinks, setSelectedPath })(withStyles(styles)(EdgeList));
D
T