Convert the rest of the views to TypeScript

Signed-off-by: Mcat12 <newtoncat12@yahoo.com>
This commit is contained in:
Mcat12
2019-01-21 11:51:34 -08:00
parent 3512b49960
commit 148a24d8a7
11 changed files with 95 additions and 37 deletions
+19
View File
@@ -1479,6 +1479,25 @@
"@types/react-router": "*"
}
},
"@types/reactstrap": {
"version": "6.4.4",
"resolved": "https://registry.npmjs.org/@types/reactstrap/-/reactstrap-6.4.4.tgz",
"integrity": "sha512-UlR5HIitjdbce/+INRwvqq6UZEjpB0hCnbTBalZbTCLGKqWQDZcCxsy5+R/IJFb+Hv6zmGsz6TlDwnikK9D7IQ==",
"dev": true,
"requires": {
"@types/react": "*",
"popper.js": "^1.14.1"
}
},
"@types/sha.js": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@types/sha.js/-/sha.js-2.4.0.tgz",
"integrity": "sha512-amxKgPy6WJTKuw8mpUwjX2BSxuBtBmZfRwIUDIuPJKNwGN8CWDli8JTg5ONTWOtcTkHIstvT7oAhhYXqEjStHQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/tapable": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz",
+2
View File
@@ -12,6 +12,8 @@
"@types/react": "^16.7.20",
"@types/react-dom": "^16.0.11",
"@types/react-router-dom": "^4.3.1",
"@types/reactstrap": "^6.4.4",
"@types/sha.js": "^2.4.0",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"faker": "^4.1.0",
+3 -1
View File
@@ -8,7 +8,9 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import { Config } from "./config";
export default {
developmentMode: true,
fakeAPI: false
};
} as Config;
+3 -1
View File
@@ -8,7 +8,9 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import { Config } from "./config";
export default {
developmentMode: false,
fakeAPI: false
};
} as Config;
+14 -4
View File
@@ -11,11 +11,21 @@
import developmentConfig from "./config.development";
import productionConfig from "./config.production";
let config: { developmentMode: boolean; fakeAPI: boolean };
export interface Config {
developmentMode: boolean;
fakeAPI: boolean;
}
if (process.env.NODE_ENV === "development") config = developmentConfig;
else config = productionConfig;
let config: Config;
if (process.env.REACT_APP_FAKE_API) config.fakeAPI = true;
if (process.env.NODE_ENV === "development") {
config = developmentConfig;
} else {
config = productionConfig;
}
if (process.env.REACT_APP_FAKE_API) {
config.fakeAPI = true;
}
export default config;
+8 -6
View File
@@ -22,7 +22,9 @@ import Preferences from "./views/Preferences";
import i18next from "i18next";
import { ComponentType } from "react";
export const routes = (t: i18next.TranslationFunction) => ({
export const routes = (
t: i18next.TranslationFunction
): { [key: string]: string } => ({
"/dashboard": t("Dashboard"),
"/query-log": t("Query Log"),
"/whitelist": t("Whitelist"),
@@ -35,23 +37,23 @@ export const routes = (t: i18next.TranslationFunction) => ({
"/logout": t("Logout")
});
interface NavItem {
export interface NavItem {
name: string;
url: string;
component: ComponentType;
component: ComponentType<any>;
icon: string;
auth: boolean;
authStrict?: boolean;
}
interface NavCustomItem {
customComponent: ComponentType;
export interface NavCustomItem {
customComponent: ComponentType<any>;
auth: boolean;
authStrict?: boolean;
fakeRoute: boolean;
}
interface NavGroup {
export interface NavGroup {
name: string;
url: string;
icon: string;
+33 -18
View File
@@ -8,17 +8,29 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import React, { Component, Fragment } from "react";
import React, { ChangeEvent, Component, FormEvent, Fragment, KeyboardEvent } from "react";
import { Redirect } from "react-router-dom";
import sha from "sha.js";
import api from "../util/api";
import logo from "../img/logo.svg";
import { routes } from "../routes";
import ForgotPassword from "../components/login/ForgotPassword";
import { withNamespaces } from "react-i18next";
import { WithNamespaces, withNamespaces } from "react-i18next";
import config from "../config";
import { History, LocationDescriptorObject } from "history";
class Login extends Component {
export interface LoginProps extends WithNamespaces {
location: LocationDescriptorObject<{ from: Location }>
history: History;
}
export interface LoginState {
password: string;
error: boolean;
cookiesEnabled: boolean;
}
class Login extends Component<LoginProps, LoginState> {
state = {
password: "",
error: false,
@@ -31,23 +43,29 @@ class Login extends Component {
}
/**
* Called when the user types into the password box.
* If they clicked Enter, try to authenticate them.
* Otherwise update the password in the state.
* Update the password in the state.
*
* @param e the event
*/
handlePasswordChange = e => {
if (e.keyCode === 13) this.authenticate();
else this.setState({ password: e.target.value });
handlePasswordChange = (e: ChangeEvent<HTMLInputElement>) => {
this.setState({ password: e.target.value });
};
/**
* If they clicked Enter, try to authenticate them.
*/
handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
this.authenticate();
}
};
/**
* Try to authenticate the user
*/
authenticate = e => {
authenticate = (e?: FormEvent) => {
// Prevent the page from reloading when the user gets redirected
e.preventDefault();
e && e.preventDefault();
// Hash the password twice before sending to the API
let hashedPassword = sha("sha256")
@@ -79,7 +97,7 @@ class Login extends Component {
}
// Redirect to the page the user was originally going to, or if that doesn't exist, go to home
const locationState = this.props.location.state || "/";
const locationState = this.props.location.state || { from: { pathname: "/" } };
this.props.history.push(locationState.from.pathname);
})
// If there was an error, tell the user they used the wrong password
@@ -142,7 +160,7 @@ class Login extends Component {
</div>
<div className="card-body">
<form id="loginform">
<form id="loginform" onSubmit={this.authenticate}>
<div
className={
"input-group" + (this.state.error ? " has-error" : "")
@@ -153,15 +171,12 @@ class Login extends Component {
className="form-control"
value={this.state.password}
onChange={this.handlePasswordChange}
onKeyDown={this.handleKeyDown}
placeholder={t("Password")}
autoFocus
/>
<div className="input-group-append">
<button
type="submit"
className="btn btn-primary"
onClick={this.authenticate}
>
<button type="submit" className="btn btn-primary">
{t("Log in")}
</button>
</div>
@@ -8,15 +8,19 @@
* 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 { withNamespaces } from "react-i18next";
import React, { Component, ReactNode } from "react";
import { WithNamespaces, withNamespaces } from "react-i18next";
import { Nav, NavItem, NavLink, TabContent, TabPane } from "reactstrap";
import DHCPInfo from "../components/settings/DHCPInfo";
import DNSInfo from "../components/settings/DNSInfo";
import NetworkInfo from "../components/settings/NetworkInfo";
import FTLInfo from "../components/settings/FTLInfo";
class Networking extends Component {
export interface NetworkingState {
activeTab: string;
}
class Networking extends Component<WithNamespaces, NetworkingState> {
state = {
activeTab: "network"
};
@@ -26,7 +30,7 @@ class Networking extends Component {
*
* @param tab the tab ID to switch to
*/
setTab = tab => {
setTab = (tab: string) => {
if (this.state.activeTab !== tab) {
this.setState({
activeTab: tab
@@ -41,7 +45,7 @@ class Networking extends Component {
* @param name the tab's display name
* @returns {NavItem} the tab component
*/
tab = (id, name) => (
tab = (id: string, name: string): ReactNode => (
<NavItem>
<NavLink
active={this.state.activeTab === id}
@@ -57,9 +61,11 @@ class Networking extends Component {
*
* @param id the tab's ID
* @param component the component to render in the tab
* @returns {TabPane} the tab content component
* @returns {ReactNode} the tab content component
*/
tabContent = (id, component) => <TabPane tabId={id}>{component}</TabPane>;
tabContent = (id: string, component: ReactNode): ReactNode => (
<TabPane tabId={id}>{component}</TabPane>
);
render() {
const { t } = this.props;