summaryrefslogtreecommitdiff
path: root/src/components/ListView.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/ListView.js')
-rw-r--r--src/components/ListView.js153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/components/ListView.js b/src/components/ListView.js
new file mode 100644
index 0000000..f68efe4
--- /dev/null
+++ b/src/components/ListView.js
@@ -0,0 +1,153 @@
+import React from "react";
+
+import Pagination from "@mui/material/Pagination";
+
+import ListItem from "./ListItem";
+import SearchForm from "./SearchForm";
+
+class ListView extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ scans: [],
+ filter: {
+ field: null,
+ value: null
+ },
+ page: 1,
+ totalPages: 1
+ };
+
+ this.filter = this.filter.bind(this);
+ this.filterString = this.filterString.bind(this);
+ this.getData = this.getData.bind(this);
+ this.queryString = this.queryString.bind(this);
+ this.setPage = this.setPage.bind(this);
+ }
+
+ componentDidMount() {
+ this.getData();
+ }
+
+ //
+ // Helpers
+ //
+
+ filterString() {
+ return this.state.filter.field == null ||
+ this.state.filter.value == null
+ ? null
+ : this.state.filter.field + "=" + this.state.filter.value;
+ }
+
+ queryString() {
+ return [
+ `limit=${window.injectedEnv.PER_PAGE}`,
+ `skip=${(this.state.page - 1) * window.injectedEnv.PER_PAGE}`,
+ this.filterString()
+ ]
+ .filter(x => x !== null)
+ .join("&");
+ }
+
+ // Fetch data from external source, update state
+ getData() {
+ fetch(
+ window.injectedEnv.COLLECTOR_URL +
+ "/sc/v0/get?" +
+ this.queryString(),
+ {
+ headers: {
+ Authorization: "Bearer " + this.props.token
+ }
+ }
+ )
+ // TODO: Look at `status` or return code or both?
+ .then(resp => {
+ if (resp.status !== 200)
+ throw new Error(
+ `Unexpected HTTP response code from soc_collector: ${resp.status} ${resp.statusText}`
+ );
+ this.setState({
+ totalPages: parseInt(resp.headers.get("X-Total-Count"))
+ });
+ return resp.json();
+ })
+ .then(json => {
+ if (json.status != "success")
+ throw new Error(
+ `Unexpected status from soc_collector: ${json.status}`
+ );
+ this.setState({
+ scans: json.docs
+ });
+ })
+ .catch(e => this.props.setError(e));
+ }
+
+ //
+ // Event handlers
+ //
+
+ filter(field, value) {
+ this.setState(
+ {
+ filter: {
+ field: field,
+ value: value
+ },
+ page: 1
+ },
+ this.getData
+ );
+ }
+
+ setPage(event, value) {
+ this.setState({ page: value }, () => {
+ this.getData();
+ window.scrollTo(0, 0);
+ });
+ }
+
+ render() {
+ return (
+ <div id="list-container">
+ <div id="controls">
+ <div id="action"></div>
+ <div id="search">
+ <SearchForm filter={this.filter} />
+ </div>
+ </div>
+ <table id="main">
+ <tbody>
+ {this.state.scans
+ .map(scan =>
+ scan.result.map(res => (
+ <ListItem
+ summary={true}
+ {...scan}
+ {...res}
+ key={scan._id + res.cve}
+ />
+ ))
+ )
+ .flat()}
+ </tbody>
+ </table>
+ <div id="pagination">
+ <Pagination
+ page={this.state.page}
+ count={this.state.totalPages}
+ onChange={this.setPage}
+ variant="outlined"
+ shape="rounded"
+ showFirstButton
+ showLastButton
+ />
+ </div>
+ </div>
+ );
+ }
+}
+
+export default ListView;