From 148a24d8a7176663b7a2d11233ee2e4f04196c88 Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Mon, 21 Jan 2019 11:51:34 -0800 Subject: [PATCH] Convert the rest of the views to TypeScript Signed-off-by: Mcat12 --- package-lock.json | 19 +++++++ package.json | 2 + src/config.development.tsx | 4 +- src/config.production.tsx | 4 +- src/config.tsx | 18 +++++-- src/routes.tsx | 14 ++--- src/views/{Login.js => Login.tsx} | 51 ++++++++++++------- src/views/{Logout.js => Logout.tsx} | 0 src/views/{Networking.js => Networking.tsx} | 20 +++++--- src/views/{Preferences.js => Preferences.tsx} | 0 src/views/{Versions.js => Versions.tsx} | 0 11 files changed, 95 insertions(+), 37 deletions(-) rename src/views/{Login.js => Login.tsx} (81%) rename src/views/{Logout.js => Logout.tsx} (100%) rename src/views/{Networking.js => Networking.tsx} (80%) rename src/views/{Preferences.js => Preferences.tsx} (100%) rename src/views/{Versions.js => Versions.tsx} (100%) diff --git a/package-lock.json b/package-lock.json index 175cc77..7a9867c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 3ff7cfc..abee016 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/config.development.tsx b/src/config.development.tsx index a76fe96..3bfa9cf 100644 --- a/src/config.development.tsx +++ b/src/config.development.tsx @@ -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; diff --git a/src/config.production.tsx b/src/config.production.tsx index cee4ff2..54fcb54 100644 --- a/src/config.production.tsx +++ b/src/config.production.tsx @@ -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; diff --git a/src/config.tsx b/src/config.tsx index 767a926..5606de8 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -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; diff --git a/src/routes.tsx b/src/routes.tsx index 9e50d5f..1c79f3f 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -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; icon: string; auth: boolean; authStrict?: boolean; } -interface NavCustomItem { - customComponent: ComponentType; +export interface NavCustomItem { + customComponent: ComponentType; auth: boolean; authStrict?: boolean; fakeRoute: boolean; } -interface NavGroup { +export interface NavGroup { name: string; url: string; icon: string; diff --git a/src/views/Login.js b/src/views/Login.tsx similarity index 81% rename from src/views/Login.js rename to src/views/Login.tsx index c8d4580..13db565 100644 --- a/src/views/Login.js +++ b/src/views/Login.tsx @@ -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 { 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) => { + this.setState({ password: e.target.value }); + }; + + /** + * If they clicked Enter, try to authenticate them. + */ + handleKeyDown = (e: KeyboardEvent) => { + 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 {
-
+
-
diff --git a/src/views/Logout.js b/src/views/Logout.tsx similarity index 100% rename from src/views/Logout.js rename to src/views/Logout.tsx diff --git a/src/views/Networking.js b/src/views/Networking.tsx similarity index 80% rename from src/views/Networking.js rename to src/views/Networking.tsx index 476058e..4783bfb 100644 --- a/src/views/Networking.js +++ b/src/views/Networking.tsx @@ -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 { 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 => ( {component}; + tabContent = (id: string, component: ReactNode): ReactNode => ( + {component} + ); render() { const { t } = this.props; diff --git a/src/views/Preferences.js b/src/views/Preferences.tsx similarity index 100% rename from src/views/Preferences.js rename to src/views/Preferences.tsx diff --git a/src/views/Versions.js b/src/views/Versions.tsx similarity index 100% rename from src/views/Versions.js rename to src/views/Versions.tsx