diff --git a/client/src/components/Dashboard/BlockedDomains.js b/client/src/components/Dashboard/BlockedDomains.js index 382a23b8..18c7ae99 100644 --- a/client/src/components/Dashboard/BlockedDomains.js +++ b/client/src/components/Dashboard/BlockedDomains.js @@ -1,34 +1,60 @@ -import React from 'react'; +import React, { Component } from 'react'; import ReactTable from 'react-table'; import PropTypes from 'prop-types'; import map from 'lodash/map'; import Card from '../ui/Card'; +import Cell from '../ui/Cell'; -const Clients = props => ( - - ( - { ip: prop, domain: value } - ))} - columns={[{ - Header: 'IP', - accessor: 'ip', - }, { - Header: 'Domain name', - accessor: 'domain', - }]} - showPagination={false} - noDataText="No domains found" - minRows={6} - className="-striped -highlight card-table-overflow" - /> - -); +import { getPercent } from '../../helpers/helpers'; +import { STATUS_COLORS } from '../../helpers/constants'; -Clients.propTypes = { +class BlockedDomains extends Component { + columns = [{ + Header: 'IP', + accessor: 'ip', + }, { + Header: 'Requests count', + accessor: 'domain', + Cell: ({ value }) => { + const { + blockedFiltering, + replacedSafebrowsing, + replacedParental, + } = this.props; + const blocked = blockedFiltering + replacedSafebrowsing + replacedParental; + const percent = getPercent(blocked, value); + + return ( + + ); + }, + }]; + + render() { + return ( + + ( + { ip: prop, domain: value } + ))} + columns={this.columns} + showPagination={false} + noDataText="No domains found" + minRows={6} + className="-striped -highlight card-table-overflow" + /> + + ); + } +} + +BlockedDomains.propTypes = { topBlockedDomains: PropTypes.object.isRequired, - refreshButton: PropTypes.node, + blockedFiltering: PropTypes.number.isRequired, + replacedSafebrowsing: PropTypes.number.isRequired, + replacedParental: PropTypes.number.isRequired, + refreshButton: PropTypes.node.isRequired, }; -export default Clients; +export default BlockedDomains; diff --git a/client/src/components/Dashboard/Clients.js b/client/src/components/Dashboard/Clients.js index a3f4ae14..136f2e2d 100644 --- a/client/src/components/Dashboard/Clients.js +++ b/client/src/components/Dashboard/Clients.js @@ -1,34 +1,62 @@ -import React from 'react'; +import React, { Component } from 'react'; import ReactTable from 'react-table'; import PropTypes from 'prop-types'; import map from 'lodash/map'; import Card from '../ui/Card'; +import Cell from '../ui/Cell'; -const Clients = props => ( - - ( - { ip: prop, count: value } - ))} - columns={[{ - Header: 'IP', - accessor: 'ip', - }, { - Header: 'Requests count', - accessor: 'count', - }]} - showPagination={false} - noDataText="No clients found" - minRows={6} - className="-striped -highlight card-table-overflow" - /> - -); +import { getPercent } from '../../helpers/helpers'; +import { STATUS_COLORS } from '../../helpers/constants'; + +class Clients extends Component { + getPercentColor = (percent) => { + if (percent > 50) { + return STATUS_COLORS.green; + } else if (percent > 10) { + return STATUS_COLORS.yellow; + } + return STATUS_COLORS.red; + } + + columns = [{ + Header: 'IP', + accessor: 'ip', + }, { + Header: 'Requests count', + accessor: 'count', + Cell: ({ value }) => { + const percent = getPercent(this.props.dnsQueries, value); + const percentColor = this.getPercentColor(percent); + + return ( + + ); + }, + }]; + + render() { + return ( + + ( + { ip: prop, count: value } + ))} + columns={this.columns} + showPagination={false} + noDataText="No clients found" + minRows={6} + className="-striped -highlight card-table-overflow" + /> + + ); + } +} Clients.propTypes = { topClients: PropTypes.object.isRequired, - refreshButton: PropTypes.node, + dnsQueries: PropTypes.number.isRequired, + refreshButton: PropTypes.node.isRequired, }; export default Clients; diff --git a/client/src/components/Dashboard/Counters.js b/client/src/components/Dashboard/Counters.js index 1b7ec92f..a6260e10 100644 --- a/client/src/components/Dashboard/Counters.js +++ b/client/src/components/Dashboard/Counters.js @@ -88,7 +88,7 @@ Counters.propTypes = { replacedParental: PropTypes.number.isRequired, replacedSafesearch: PropTypes.number.isRequired, avgProcessingTime: PropTypes.number.isRequired, - refreshButton: PropTypes.node, + refreshButton: PropTypes.node.isRequired, }; export default Counters; diff --git a/client/src/components/Dashboard/QueriedDomains.js b/client/src/components/Dashboard/QueriedDomains.js index fd756e0e..2808e625 100644 --- a/client/src/components/Dashboard/QueriedDomains.js +++ b/client/src/components/Dashboard/QueriedDomains.js @@ -1,34 +1,62 @@ -import React from 'react'; +import React, { Component } from 'react'; import ReactTable from 'react-table'; import PropTypes from 'prop-types'; import map from 'lodash/map'; import Card from '../ui/Card'; +import Cell from '../ui/Cell'; -const QueriedDomains = props => ( - - ( - { ip: prop, count: value } - ))} - columns={[{ - Header: 'IP', - accessor: 'ip', - }, { - Header: 'Requests count', - accessor: 'count', - }]} - showPagination={false} - noDataText="No domains found" - minRows={6} - className="-striped -highlight card-table-overflow" - /> - -); +import { getPercent } from '../../helpers/helpers'; +import { STATUS_COLORS } from '../../helpers/constants'; + +class QueriedDomains extends Component { + getPercentColor = (percent) => { + if (percent > 10) { + return STATUS_COLORS.red; + } else if (percent > 5) { + return STATUS_COLORS.yellow; + } + return STATUS_COLORS.green; + } + + columns = [{ + Header: 'IP', + accessor: 'ip', + }, { + Header: 'Requests count', + accessor: 'count', + Cell: ({ value }) => { + const percent = getPercent(this.props.dnsQueries, value); + const percentColor = this.getPercentColor(percent); + + return ( + + ); + }, + }]; + + render() { + return ( + + ( + { ip: prop, count: value } + ))} + columns={this.columns} + showPagination={false} + noDataText="No domains found" + minRows={6} + className="-striped -highlight card-table-overflow" + /> + + ); + } +} QueriedDomains.propTypes = { topQueriedDomains: PropTypes.object.isRequired, - refreshButton: PropTypes.node, + dnsQueries: PropTypes.number.isRequired, + refreshButton: PropTypes.node.isRequired, }; export default QueriedDomains; diff --git a/client/src/components/Dashboard/index.js b/client/src/components/Dashboard/index.js index 28d52f11..99fe8e5e 100644 --- a/client/src/components/Dashboard/index.js +++ b/client/src/components/Dashboard/index.js @@ -61,6 +61,10 @@ class Dashboard extends Component { } @@ -81,12 +85,14 @@ class Dashboard extends Component {
@@ -95,6 +101,9 @@ class Dashboard extends Component {
diff --git a/client/src/components/ui/Card.css b/client/src/components/ui/Card.css index 0aaeea01..b02c1409 100644 --- a/client/src/components/ui/Card.css +++ b/client/src/components/ui/Card.css @@ -26,7 +26,6 @@ display: flex; align-items: center; justify-content: center; - height: 400px; } .card-body--status { @@ -48,3 +47,40 @@ .card-refresh:focus:active { background-image: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI0IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjMgNHY2aC02Ii8+PHBhdGggZD0ibTEgMjB2LTZoNiIvPjxwYXRoIGQ9Im0zLjUxIDlhOSA5IDAgMCAxIDE0Ljg1LTMuMzZsNC42NCA0LjM2bS0yMiA0IDQuNjQgNC4zNmE5IDkgMCAwIDAgMTQuODUtMy4zNiIvPjwvc3ZnPg=="); } + +.card-title-stats { + color: #9aa0ac; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.card-body-stats { + position: relative; + flex: 1 1 auto; + margin: 0; + padding: 1rem 1.5rem; +} + +.card-value-stats { + display: block; + font-size: 2.1rem; + line-height: 2.7rem; + height: 2.7rem; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.card-value-percent { + position: absolute; + top: 15px; + right: 15px; + font-size: 0.9rem; + line-height: 1; + height: auto; +} + +.card-value-percent:after { + content: "%"; +} diff --git a/client/src/components/ui/Cell.js b/client/src/components/ui/Cell.js new file mode 100644 index 00000000..243b48b2 --- /dev/null +++ b/client/src/components/ui/Cell.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const Cell = props => ( +
+
+ {props.value} + + {props.percent}% + +
+
+
+
+
+); + +Cell.propTypes = { + value: PropTypes.number.isRequired, + percent: PropTypes.number.isRequired, + color: PropTypes.string.isRequired, +}; + +export default Cell; diff --git a/client/src/helpers/helpers.js b/client/src/helpers/helpers.js index 7013c9c0..d21ba510 100644 --- a/client/src/helpers/helpers.js +++ b/client/src/helpers/helpers.js @@ -75,4 +75,9 @@ export const normalizeFilteringStatus = (filteringStatus) => { return { enabled, userRules: newUserRules, filters: newFilters }; }; -export const getPercent = (amount, number) => round(100 / (amount / number)); +export const getPercent = (amount, number) => { + if (amount > 0 && number > 0) { + return round(100 / (amount / number), 2); + } + return 0; +};