Implement DnsList components

These components will display an editable list of upstream DNS servers.

Signed-off-by: Mcat12 <newtoncat12@yahoo.com>
This commit is contained in:
Mcat12
2018-11-30 17:36:45 -05:00
parent 8f84a66dbc
commit b0a377f80c
3 changed files with 139 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* Web Interface
* An Editable List of Upstream DNS Servers
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import React from "react";
import PropTypes from "prop-types";
import { ListGroup } from "reactstrap";
import DnsListItem from "./DnsListItem";
import DnsListNewItem from "./DnsListNewItem";
import { isValidIpv4OptionalPort } from "../../validate";
/**
* Check if an upstream address is unique and valid
*
* @param address the address to check
* @param upstreams the list of current upstreams
* @returns {boolean} if the upstream address is unique and valid
*/
export const isAddressValid = (address, upstreams) =>
!upstreams.includes(address) && isValidIpv4OptionalPort(address);
const DnsList = ({ upstreams, onAdd, onRemove }) => (
<ListGroup style={{ overflowY: "scroll", maxHeight: "350px" }}>
{upstreams.map(upstream => (
<DnsListItem
key={upstream}
onRemove={() => onRemove(upstream)}
address={upstream}
/>
))}
<DnsListNewItem
onAdd={onAdd}
isValid={address => isAddressValid(address, upstreams)}
/>
</ListGroup>
);
DnsList.propTypes = {
upstreams: PropTypes.arrayOf(PropTypes.string).isRequired,
onAdd: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired
};
export default DnsList;
+29
View File
@@ -0,0 +1,29 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* Web Interface
* A Upstream DNS List Item
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import React from "react";
import PropTypes from "prop-types";
import { Button, ListGroupItem } from "reactstrap";
const DnsListItem = ({ address, onRemove }) => (
<ListGroupItem>
{address}
<Button color="danger" size="sm" className="pull-right" onClick={onRemove}>
<span className="fa fa-trash-o" />
</Button>
</ListGroupItem>
);
DnsListItem.propTypes = {
address: PropTypes.string.isRequired,
onRemove: PropTypes.func.isRequired
};
export default DnsListItem;
+60
View File
@@ -0,0 +1,60 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* Web Interface
* Input For New DNS List Items
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import React, { Component } from "react";
import PropTypes from "prop-types";
import {
Button,
Input,
InputGroup,
InputGroupAddon,
ListGroupItem
} from "reactstrap";
export default class DnsListNewItem extends Component {
static propTypes = {
onAdd: PropTypes.func.isRequired,
isValid: PropTypes.func.isRequired
};
state = {
address: ""
};
render() {
const isAddressValid = this.props.isValid(this.state.address);
return (
<ListGroupItem>
<InputGroup>
<Input
type="text"
value={this.state.address}
onChange={e => this.setState({ address: e.target.value })}
/>
<InputGroupAddon addonType="append">
<Button
color="success"
size="sm"
className="pull-right"
onClick={() => {
this.props.onAdd(this.state.address);
this.setState({ address: "" });
}}
disabled={!isAddressValid}
>
<span className="fa fa-plus" />
</Button>
</InputGroupAddon>
</InputGroup>
</ListGroupItem>
);
}
}