Skip to content

Commit

Permalink
Created Testflow Details Page (#45)
Browse files Browse the repository at this point in the history
* Created basic UI

* Binded UI with kube-api

* Fixed match and filter mismatch

* Added tooltips

* Seperated passing and failling tests

* Added a badge to show status
  • Loading branch information
isala404 authored Aug 11, 2021
1 parent e3988b7 commit f9dc3ce
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 9 deletions.
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"json-to-pretty-yaml": "^1.2.2",
"notistack": "^1.0.10",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
2 changes: 1 addition & 1 deletion ui/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function App() {
<Route path="/create">
<CreateView />
</Route>
<Route path="/flowtest/:uuid">
<Route path="/flowtest/:namespace/:name">
<DetailView />
</Route>
</Switch>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/FlowList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function FlowList() {
autoHeight
disableExtendRowFullWidth
onSelectionModelChange={getSelectedFlows}
onRowClick={(row) => history.push(`flowtest/${row.row.uuid}`)}
onRowClick={(row) => history.push(`flowtest/${row.row.namespace}/${row.row.name}`)}
/>
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion ui/src/components/ParseTextarea.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const ParseTextarea = ({
const handleChange = (e) => {
const newValue = e.target.value;
setText(newValue);
onChange(newValue.split('\n'));
// Remove the last line if it's empty
// eslint-disable-next-line no-shadow
onChange(newValue.split('\n').filter((e) => e));
};

return <TextareaAutosize onChange={handleChange} value={text} style={{ height: '180px', width: '750px' }} required={required} />;
Expand Down
34 changes: 34 additions & 0 deletions ui/src/components/TestStatus.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* eslint-disable react/prop-types */
import * as React from 'react';
import { Grid } from '@material-ui/core';
import YAML from 'json-to-pretty-yaml';

const TestStatus = ({
type, tests, status,
}) => (
<>
<div style={{ margin: '10px' }}>
{`Tested ${type}`}
</div>
<Grid container style={{ marginLeft: '30px' }}>
<Grid item xs={12}>
<div>
{tests?.map((match, index) => (
<div style={{ display: 'table' }}>
{
status[index]
? <div className="badge-wrapper"><span className="badge badge-pass">Pass</span></div>
: <div className="badge-wrapper"><span className="badge badge-fail">Fail</span></div>
}
<pre style={{ display: 'inline-block', color: status[index] ? 'green' : 'red' }}>
{ YAML.stringify(match) }
</pre>
</div>
))}
</div>
</Grid>
</Grid>
</>
);

export default TestStatus;
33 changes: 33 additions & 0 deletions ui/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,36 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

pre {
white-space: pre-wrap;
}

.badge-wrapper {
display: table-cell;
vertical-align: middle;
width: 50px;
}

.badge {
display: inline-block;
padding: .25em .4em;
font-size: 75%;
font-weight: 700;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25rem;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}

.badge-fail {
color: #fff;
background-color: #dc3545;
}

.badge-pass {
color: #fff;
background-color: #28a745;
}
65 changes: 59 additions & 6 deletions ui/src/pages/DetailPage.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,67 @@
import * as React from 'react';
import Container from '@material-ui/core/Container';
import React, { useEffect, useState } from 'react';
import {
Container, Grid, Paper,
} from '@material-ui/core';
import { useParams } from 'react-router-dom';
import { getFlow, getFlowTest } from '../utils/flowtests/flowDetails';
import TestStatus from '../components/TestStatus';

export default function DetailView() {
const { uuid } = useParams();
const { namespace, name } = useParams();
const [flowTest, setFlowTest] = useState(undefined);
const [flow, setFlow] = useState(undefined);

useEffect(async () => {
if (flowTest?.spec?.referenceFlow) {
setFlow(await getFlow(
flowTest.spec.referenceFlow.namespace,
flowTest.spec.referenceFlow.kind,
flowTest.spec.referenceFlow.name,
));
}
}, [flowTest]);

useEffect(async () => {
setFlowTest(await getFlowTest(namespace, name));
}, []);

return (
<Container style={{ width: '95%', maxWidth: '100%' }}>
<h1>
{`Detail View for flowtest ${uuid}`}
</h1>
<h1>{name}</h1>
<h3>Details</h3>
<Paper>
<Grid container spacing={3}>
<Grid item xs={12} xl={6}>
<div style={{ margin: '10px' }}>
Status:
{` ${flowTest?.status?.status}`}
</div>
<div style={{ margin: '10px' }}>Reference Flow</div>
<div style={{ marginLeft: '30px' }}>
<div>{`Kind: ${flowTest?.spec.referenceFlow.kind}`}</div>
<div>{`Namespace: ${flowTest?.spec.referenceFlow.namespace}`}</div>
<div>{`Name: ${flowTest?.spec.referenceFlow.name}`}</div>
</div>
<div style={{ margin: '10px' }}>Reference Pod</div>
<div style={{ marginLeft: '30px' }}>
<div>{`Namespace: ${flowTest?.spec.referencePod.namespace}`}</div>
<div>{`Name: ${flowTest?.spec.referencePod.name}`}</div>
</div>
<div style={{ margin: '10px' }}>Testing Logs</div>
<div style={{ marginLeft: '30px' }}>
{flowTest?.spec?.sentMessages?.map((message) => (
<pre>
{ message }
</pre>
))}
</div>
</Grid>
<Grid item xs={12} xl={6}>
<TestStatus type="Matches" tests={flow?.spec?.match} status={flowTest?.status?.matchStatus} />
<TestStatus type="Filters" tests={flow?.spec?.filters} status={flowTest?.status?.filterStatus} />
</Grid>
</Grid>
</Paper>
</Container>
);
}
31 changes: 31 additions & 0 deletions ui/src/utils/flowtests/flowDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable no-param-reassign */
import axios from 'axios';
import snackbarUtils from '../../libs/snackbarUtils';

export const getFlow = async (namespace, kind, name) => {
try {
const res = await axios.get(`k8s/apis/logging.banzaicloud.io/v1beta1/namespaces/${namespace}/${kind.toLowerCase()}s/${name}`);
return res.data;
} catch (error) {
snackbarUtils.error(`[HTTP error]: ${error.message}`);
snackbarUtils.warning(`Failed to fetch ${kind} ${namespace}.${name}`);
}
return null;
};

export const getFlowTest = async (namespace, name) => {
try {
const res = await axios.get(`k8s/apis/loggingplumber.isala.me/v1alpha1/namespaces/${namespace}/flowtests/${name}`);
return res.data;
} catch (error) {
snackbarUtils.error(`[HTTP error]: ${error.message}`);
snackbarUtils.warning(`Failed to fetch flowtest ${namespace}.${name}`);
}
return null;
};

export const cleanFlowTest = (flowTest) => {
delete flowTest?.metadata.generation;
delete flowTest?.metadata.managedFields;
return flowTest;
};
18 changes: 18 additions & 0 deletions ui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7144,6 +7144,14 @@ json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=

json-to-pretty-yaml@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz#f4cd0bd0a5e8fe1df25aaf5ba118b099fd992d5b"
integrity sha1-9M0L0KXo/h3yWq9boRiwmf2ZLVs=
dependencies:
remedial "^1.0.7"
remove-trailing-spaces "^1.0.6"

json3@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
Expand Down Expand Up @@ -9940,11 +9948,21 @@ relateurl@^0.2.7:
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=

remedial@^1.0.7:
version "1.0.8"
resolved "https://registry.yarnpkg.com/remedial/-/remedial-1.0.8.tgz#a5e4fd52a0e4956adbaf62da63a5a46a78c578a0"
integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==

remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=

remove-trailing-spaces@^1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz#4354d22f3236374702f58ee373168f6d6887ada7"
integrity sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==

renderkid@^2.0.4:
version "2.0.5"
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.5.tgz#483b1ac59c6601ab30a7a596a5965cabccfdd0a5"
Expand Down

0 comments on commit f9dc3ce

Please sign in to comment.