mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
cleanup
This commit is contained in:
@@ -1,343 +0,0 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
Flex,
|
||||
Icon,
|
||||
Popover,
|
||||
PopoverArrow,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
Text,
|
||||
Tooltip,
|
||||
useColorMode
|
||||
} from "@chakra-ui/core";
|
||||
import dayjs from "dayjs";
|
||||
import relativeTimePlugin from "dayjs/plugin/relativeTime";
|
||||
import utcPlugin from "dayjs/plugin/utc";
|
||||
import useConfig from "~/components/HyperglassProvider";
|
||||
import Layout from "~/components/Layout";
|
||||
import Table from "~/components/Table/index";
|
||||
|
||||
dayjs.extend(relativeTimePlugin);
|
||||
dayjs.extend(utcPlugin);
|
||||
|
||||
const data = {
|
||||
vrf: "default",
|
||||
prefix: "1.1.1.0/24",
|
||||
count: 4,
|
||||
routes: [
|
||||
{
|
||||
active: true,
|
||||
age: 578857,
|
||||
weight: 170,
|
||||
med: 0,
|
||||
local_preference: 150,
|
||||
as_path: [1299, 13335],
|
||||
communities: [
|
||||
"1299:35000",
|
||||
"14525:0",
|
||||
"14525:40",
|
||||
"14525:1021",
|
||||
"14525:2840",
|
||||
"14525:3001",
|
||||
"14525:4001",
|
||||
"14525:9003"
|
||||
],
|
||||
next_hop: "62.115.189.136",
|
||||
source_as: 13335,
|
||||
source_rid: "162.158.140.1",
|
||||
peer_rid: "2.255.254.51",
|
||||
rpki_state: 1
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
age: 787213,
|
||||
weight: 170,
|
||||
med: 2020,
|
||||
local_preference: 150,
|
||||
as_path: [174, 13335],
|
||||
communities: [
|
||||
"174:21001",
|
||||
"174:22013",
|
||||
"14525:0",
|
||||
"14525:20",
|
||||
"14525:1021",
|
||||
"14525:2840",
|
||||
"14525:3001",
|
||||
"14525:4001",
|
||||
"14525:9001"
|
||||
],
|
||||
next_hop: "100.64.0.122",
|
||||
source_as: 13335,
|
||||
source_rid: "162.158.140.1",
|
||||
peer_rid: "199.34.92.1",
|
||||
rpki_state: 0
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
age: 616677,
|
||||
weight: 200,
|
||||
med: 0,
|
||||
local_preference: 150,
|
||||
as_path: [6939, 13335],
|
||||
communities: [
|
||||
"6939:7107",
|
||||
"6939:8840",
|
||||
"6939:9001",
|
||||
"14525:0",
|
||||
"14525:40",
|
||||
"14525:1021",
|
||||
"14525:2840",
|
||||
"14525:3002",
|
||||
"14525:4003",
|
||||
"14525:9002"
|
||||
],
|
||||
next_hop: "100.64.0.122",
|
||||
source_as: 13335,
|
||||
source_rid: "172.68.129.1",
|
||||
peer_rid: "199.34.92.6",
|
||||
rpki_state: 2
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
age: 1284244,
|
||||
weight: 200,
|
||||
med: 25090,
|
||||
local_preference: 150,
|
||||
as_path: [174, 13335],
|
||||
communities: [],
|
||||
next_hop: "100.64.0.122",
|
||||
source_as: 13335,
|
||||
source_rid: "108.162.239.1",
|
||||
peer_rid: "199.34.92.7",
|
||||
rpki_state: 3
|
||||
}
|
||||
],
|
||||
winning_weight: "low"
|
||||
};
|
||||
|
||||
const hiddenCols = ["active", "source_as"];
|
||||
|
||||
const isActiveColor = {
|
||||
true: { dark: "green.300", light: "green.500" },
|
||||
false: { dark: "gray.300", light: "gray.500" }
|
||||
};
|
||||
|
||||
const arrowColor = {
|
||||
true: { dark: "blackAlpha.500", light: "blackAlpha.500" },
|
||||
false: { dark: "whiteAlpha.300", light: "blackAlpha.500" }
|
||||
};
|
||||
|
||||
const rpkiIcon = ["not-allowed", "check-circle", "warning", "question"];
|
||||
|
||||
const rpkiColor = {
|
||||
true: {
|
||||
dark: ["red.500", "green.600", "yellow.500", "gray.800"],
|
||||
light: ["red.500", "green.500", "yellow.500", "gray.600"]
|
||||
},
|
||||
false: {
|
||||
dark: ["red.300", "green.300", "yellow.300", "gray.300"],
|
||||
light: ["red.400", "green.500", "yellow.400", "gray.500"]
|
||||
}
|
||||
};
|
||||
|
||||
const makeColumns = fields => {
|
||||
return fields.map(pair => {
|
||||
const [header, accessor, align] = pair;
|
||||
let columnConfig = {
|
||||
Header: header,
|
||||
accessor: accessor,
|
||||
align: align,
|
||||
hidden: false
|
||||
};
|
||||
if (align === null) {
|
||||
columnConfig.hidden = true;
|
||||
}
|
||||
return columnConfig;
|
||||
});
|
||||
};
|
||||
|
||||
const longestASNLength = asPath => {
|
||||
const longest = asPath.reduce((l, c) => {
|
||||
const strLongest = String(l);
|
||||
const strCurrent = String(c);
|
||||
return strCurrent.length > strLongest.length ? strCurrent : strLongest;
|
||||
});
|
||||
return longest.length;
|
||||
};
|
||||
|
||||
const MonoField = ({ v, ...props }) => (
|
||||
<Text fontSize="sm" fontFamily="mono" {...props}>
|
||||
{v}
|
||||
</Text>
|
||||
);
|
||||
|
||||
const Active = ({ isActive }) => {
|
||||
const { colorMode } = useColorMode();
|
||||
return (
|
||||
<Icon
|
||||
name={isActive ? "check-circle" : "warning"}
|
||||
color={isActiveColor[isActive][colorMode]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Age = ({ inSeconds }) => {
|
||||
const now = dayjs.utc();
|
||||
const then = now.subtract(inSeconds, "seconds");
|
||||
return (
|
||||
<Tooltip
|
||||
hasArrow
|
||||
label={then.toString().replace("GMT", "UTC")}
|
||||
placement="right"
|
||||
>
|
||||
<Text fontSize="sm">{now.to(then, true)}</Text>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const Weight = ({ weight, winningWeight }) => {
|
||||
const fixMeText =
|
||||
winningWeight === "low"
|
||||
? "Lower Weight is Preferred"
|
||||
: "Higher Weight is Preferred";
|
||||
return (
|
||||
<Tooltip hasArrow label={fixMeText} placement="right">
|
||||
<Text fontSize="sm" fontFamily="mono">
|
||||
{weight}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const ASPath = ({ path, active, longestASN }) => {
|
||||
const { colorMode } = useColorMode();
|
||||
let paths = [];
|
||||
path.map((asn, i) => {
|
||||
const asnStr = String(asn);
|
||||
i !== 0 &&
|
||||
paths.push(
|
||||
<Icon
|
||||
name="chevron-right"
|
||||
key={`separator-${i}`}
|
||||
color={arrowColor[active][colorMode]}
|
||||
/>
|
||||
);
|
||||
paths.push(
|
||||
<Text
|
||||
fontSize="sm"
|
||||
as="span"
|
||||
whiteSpace="pre"
|
||||
fontFamily="mono"
|
||||
key={`as-${asnStr}-${i}`}
|
||||
>
|
||||
{asnStr}
|
||||
</Text>
|
||||
);
|
||||
});
|
||||
return paths;
|
||||
};
|
||||
|
||||
const Communities = ({ communities }) => {
|
||||
const { colorMode } = useColorMode();
|
||||
let component;
|
||||
communities.length === 0
|
||||
? (component = (
|
||||
<Tooltip placement="right" hasArrow label="No Communities">
|
||||
<Icon name="question-outline" />
|
||||
</Tooltip>
|
||||
))
|
||||
: (component = (
|
||||
<Popover trigger="hover" placement="right">
|
||||
<PopoverTrigger>
|
||||
<Icon name="view" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
textAlign="left"
|
||||
p={4}
|
||||
maxW="fit-content"
|
||||
color={colorMode === "dark" ? "white" : "black"}
|
||||
>
|
||||
<PopoverArrow />
|
||||
{communities.map(c => (
|
||||
<MonoField fontWeight="normal" v={c} key={c.replace(":", "-")} />
|
||||
))}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
));
|
||||
return component;
|
||||
};
|
||||
|
||||
const RPKIState = ({ state, active }) => {
|
||||
const { web } = useConfig();
|
||||
const { colorMode } = useColorMode();
|
||||
const stateText = [
|
||||
web.text.rpki_invalid,
|
||||
web.text.rpki_valid,
|
||||
web.text.rpki_unknown,
|
||||
web.text.rpki_unverified
|
||||
];
|
||||
return (
|
||||
<Tooltip
|
||||
hasArrow
|
||||
placement="right"
|
||||
label={stateText[state] ?? stateText[3]}
|
||||
>
|
||||
<Icon
|
||||
name={rpkiIcon[state]}
|
||||
color={rpkiColor[active][colorMode][state]}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const Cell = ({ data, rawData, longestASN }) => {
|
||||
const component = {
|
||||
active: <Active isActive={data.value} />,
|
||||
age: <Age inSeconds={data.value} />,
|
||||
weight: (
|
||||
<Weight weight={data.value} winningWeight={rawData.winning_weight} />
|
||||
),
|
||||
med: <MonoField v={data.value} />,
|
||||
local_preference: <MonoField v={data.value} />,
|
||||
as_path: (
|
||||
<ASPath
|
||||
path={data.value}
|
||||
active={data.row.values.active}
|
||||
longestASN={longestASN}
|
||||
/>
|
||||
),
|
||||
communities: <Communities communities={data.value} />,
|
||||
next_hop: <MonoField v={data.value} />,
|
||||
source_as: <MonoField v={data.value} />,
|
||||
source_rid: <MonoField v={data.value} />,
|
||||
peer_rid: <MonoField v={data.value} />,
|
||||
rpki_state: <RPKIState state={data.value} active={data.row.values.active} />
|
||||
};
|
||||
return component[data.column.id] ?? <> </>;
|
||||
};
|
||||
|
||||
const Structured = () => {
|
||||
const config = useConfig();
|
||||
const columns = makeColumns(config.parsed_data_fields);
|
||||
const allASN = data.routes.map(r => r.as_path).flat();
|
||||
const asLength = longestASNLength(allASN);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Flex my={8} maxW={["100%", "100%", "75%", "50%"]} w="100%">
|
||||
<Table
|
||||
columns={columns}
|
||||
data={data.routes}
|
||||
rowHighlightProp="active"
|
||||
cellRender={d => (
|
||||
<Cell data={d} rawData={data} longestASN={asLength} />
|
||||
)}
|
||||
bordersHorizontal
|
||||
rowHighlightBg="green"
|
||||
/>
|
||||
</Flex>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Structured;
|
Reference in New Issue
Block a user