diff --git a/src/components/settings/DnsList.js b/src/components/settings/DnsList.js new file mode 100644 index 0000000..5ac16a3 --- /dev/null +++ b/src/components/settings/DnsList.js @@ -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 }) => ( + + {upstreams.map(upstream => ( + onRemove(upstream)} + address={upstream} + /> + ))} + isAddressValid(address, upstreams)} + /> + +); + +DnsList.propTypes = { + upstreams: PropTypes.arrayOf(PropTypes.string).isRequired, + onAdd: PropTypes.func.isRequired, + onRemove: PropTypes.func.isRequired +}; + +export default DnsList; diff --git a/src/components/settings/DnsListItem.js b/src/components/settings/DnsListItem.js new file mode 100644 index 0000000..276c50c --- /dev/null +++ b/src/components/settings/DnsListItem.js @@ -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 }) => ( + + {address} + + +); + +DnsListItem.propTypes = { + address: PropTypes.string.isRequired, + onRemove: PropTypes.func.isRequired +}; + +export default DnsListItem; diff --git a/src/components/settings/DnsListNewItem.js b/src/components/settings/DnsListNewItem.js new file mode 100644 index 0000000..173545b --- /dev/null +++ b/src/components/settings/DnsListNewItem.js @@ -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 ( + + + this.setState({ address: e.target.value })} + /> + + + + + + ); + } +}