mirror of
https://github.com/gosticks/web.git
synced 2026-10-06 14:47:32 +00:00
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:
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user