From cec481e13ed7c3d51676aee9578e2eead0474ac4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Sat, 1 Jun 2019 03:25:17 +0000 Subject: [PATCH 1/2] Bump react-i18next from 9.0.7 to 10.11.0 Bumps [react-i18next](https://github.com/i18next/react-i18next) from 9.0.7 to 10.11.0. - [Release notes](https://github.com/i18next/react-i18next/releases) - [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/react-i18next/compare/v9.0.7...v10.11.0) --- package-lock.json | 15 +++------------ package.json | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54a6249..6f5becb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18764,12 +18764,11 @@ "dev": true }, "react-i18next": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-9.0.7.tgz", - "integrity": "sha512-+MaYI/MrjHPgcyKapuCflWurLB1GeOkzoU9qU1OAz9Lt3xxZo7q7IULhQQjH433kabikUu1qbiKx2n5MaCCH/A==", + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-10.11.0.tgz", + "integrity": "sha512-jmxLZK8mf+KxG3RUIiu/COperTq1c7+iHNsna7LODOYEYaoj6EXFuchOytnB80GoUOb0JC1csT37Zp+U5nPQqQ==", "requires": { "@babel/runtime": "^7.3.1", - "hoist-non-react-statics": "3.2.1", "html-parse-stringify2": "2.0.1" }, "dependencies": { @@ -18781,14 +18780,6 @@ "regenerator-runtime": "^0.13.2" } }, - "hoist-non-react-statics": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.2.1.tgz", - "integrity": "sha512-TFsu3TV3YLY+zFTZDrN8L2DTFanObwmBLpWvJs1qfUuEQ5bTAdFcwfx2T/bsCXfM9QHSLvjfP+nihEl0yvozxw==", - "requires": { - "react-is": "^16.3.2" - } - }, "regenerator-runtime": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", diff --git a/package.json b/package.json index 2a2df25..14d5e37 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "react-bootstrap-typeahead": "^3.4.4", "react-chartjs-2": "^2.7.6", "react-dom": "^16.8.6", - "react-i18next": "^9.0.7", + "react-i18next": "^10.11.0", "react-router-dom": "^5.0.0", "react-table": "^6.10.0", "reactstrap": "^8.0.0", From f4078537474a299ab9fad63809de58560cf2b0ca Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Fri, 31 May 2019 21:33:05 -0700 Subject: [PATCH 2/2] Migrate to v10 of react-i18next - Convert from `withNamespaces` to `withTranslation` - Fix react-i18next initialization - Use Suspense to avoid missing translation warnings, due to the `wait` option being removed. See #248 for the next steps for Suspense. - Replaced usages of `Subtract` (provided by v9 of react-i18next) with `Omit` which is provided by TypeScript as of 3.5 Signed-off-by: Mcat12 --- src/components/common/EnableDisable.tsx | 6 ++--- src/components/common/Footer.tsx | 12 +++++++--- src/components/common/FooterUpdateStatus.tsx | 6 ++--- src/components/common/Sidebar.tsx | 14 +++++++---- src/components/common/StatusBadge.tsx | 6 ++--- .../common/__tests__/Sidebar.test.tsx | 4 +++- src/components/dashboard/ClientsGraph.tsx | 8 +++---- src/components/dashboard/QueriesGraph.tsx | 6 ++--- src/components/dashboard/QueryTypesChart.tsx | 8 +++---- src/components/dashboard/SummaryStats.tsx | 6 ++--- .../dashboard/TimeRangeSelector.tsx | 24 ++++++++++--------- .../dashboard/TopBlockedClients.tsx | 8 +++---- .../dashboard/TopBlockedDomains.tsx | 8 +++---- src/components/dashboard/TopClients.tsx | 8 +++---- src/components/dashboard/TopDomains.tsx | 8 +++---- src/components/dashboard/TopTable.tsx | 3 +-- src/components/dashboard/UpstreamsChart.tsx | 8 +++---- src/components/list/DomainInput.tsx | 6 ++--- src/components/list/DomainList.tsx | 6 ++--- src/components/list/ListPage.tsx | 6 ++--- src/components/log/QueryLog.tsx | 10 ++++---- src/components/login/ForgotPassword.tsx | 6 ++--- src/components/settings/DHCPInfo.tsx | 6 ++--- src/components/settings/DNSInfo.tsx | 6 ++--- src/components/settings/DnsListNewItem.tsx | 8 +++---- src/components/settings/FTLInfo.tsx | 6 ++--- src/components/settings/NetworkInfo.tsx | 8 +++---- .../settings/PreferenceSettings.tsx | 6 ++--- src/components/settings/VersionCard.tsx | 6 ++--- src/components/settings/VersionInfo.tsx | 6 ++--- .../settings/__tests__/DHCPInfo.test.tsx | 8 +++---- src/containers/Full.tsx | 14 ++++++----- src/setupTests.tsx | 4 ++-- src/util/__tests__/i18n.test.tsx | 2 +- src/util/i18n.tsx | 8 ++----- src/views/Blacklist.tsx | 6 ++--- src/views/Login.tsx | 6 ++--- src/views/Networking.tsx | 6 ++--- src/views/Regexlist.tsx | 6 ++--- src/views/Whitelist.tsx | 6 ++--- 40 files changed, 155 insertions(+), 140 deletions(-) diff --git a/src/components/common/EnableDisable.tsx b/src/components/common/EnableDisable.tsx index 467e9cb..7e30e81 100644 --- a/src/components/common/EnableDisable.tsx +++ b/src/components/common/EnableDisable.tsx @@ -11,7 +11,7 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ import React, { Component, FormEvent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import NavButton from "./NavButton"; import NavDropdown from "./NavDropdown"; import { StatusContext } from "./context/StatusContext"; @@ -32,7 +32,7 @@ import { ModalHeader } from "reactstrap"; -export interface EnableDisableProps extends WithNamespaces { +export interface EnableDisableProps extends WithTranslation { status: Status; refresh: (data?: ApiStatus) => void; onSetStatus: ( @@ -249,7 +249,7 @@ export class EnableDisable extends Component< } } -export const TranslatedEnableDisable = withNamespaces("common")(EnableDisable); +export const TranslatedEnableDisable = withTranslation("common")(EnableDisable); export const EnableDisableContainer = () => ( diff --git a/src/components/common/Footer.tsx b/src/components/common/Footer.tsx index 7185600..4235f1e 100644 --- a/src/components/common/Footer.tsx +++ b/src/components/common/Footer.tsx @@ -8,8 +8,8 @@ * 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 { withNamespaces } from "react-i18next"; +import React, { Suspense } from "react"; +import { withTranslation } from "react-i18next"; import FooterUpdateStatus from "./FooterUpdateStatus"; const Footer = (props: any) => { @@ -32,4 +32,10 @@ const Footer = (props: any) => { ); }; -export default withNamespaces(["common", "footer"])(Footer); +const TranslatedFooter = withTranslation(["common", "footer"])(Footer); + +export default () => ( + + + +); diff --git a/src/components/common/FooterUpdateStatus.tsx b/src/components/common/FooterUpdateStatus.tsx index f602d25..cabe53c 100644 --- a/src/components/common/FooterUpdateStatus.tsx +++ b/src/components/common/FooterUpdateStatus.tsx @@ -9,10 +9,10 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { Link } from "react-router-dom"; -const FooterUpdateStatus = (props: WithNamespaces) => { +const FooterUpdateStatus = (props: WithTranslation) => { const { t } = props; const updateAvailable = false; @@ -27,4 +27,4 @@ const FooterUpdateStatus = (props: WithNamespaces) => { } }; -export default withNamespaces("footer")(FooterUpdateStatus); +export default withTranslation("footer")(FooterUpdateStatus); diff --git a/src/components/common/Sidebar.tsx b/src/components/common/Sidebar.tsx index 625cf5c..fc6665e 100644 --- a/src/components/common/Sidebar.tsx +++ b/src/components/common/Sidebar.tsx @@ -8,8 +8,8 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React, { Fragment, ReactElement } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import React, { Fragment, ReactElement, Suspense } from "react"; +import { WithTranslation, withTranslation } from "react-i18next"; import { NavLink } from "react-router-dom"; import { Nav, NavItem } from "reactstrap"; import logo from "../../img/logo.svg"; @@ -124,7 +124,7 @@ export const NavList = ({ ); -export interface SidebarProps extends WithNamespaces { +export interface SidebarProps extends WithTranslation { items: Array; location: Location; } @@ -172,4 +172,10 @@ const Sidebar = ({ items, t, location }: SidebarProps): ReactElement => ( ); -export default withNamespaces(["common", "location"])(Sidebar); +const TranslatedSidebar = withTranslation(["common", "location"])(Sidebar); + +export default (props: any) => ( + + + +); diff --git a/src/components/common/StatusBadge.tsx b/src/components/common/StatusBadge.tsx index f5da351..c20b638 100644 --- a/src/components/common/StatusBadge.tsx +++ b/src/components/common/StatusBadge.tsx @@ -9,10 +9,10 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { StatusContext } from "./context/StatusContext"; -export interface StatusBadgeProps extends WithNamespaces { +export interface StatusBadgeProps extends WithTranslation { status: string; } @@ -36,7 +36,7 @@ class StatusBadge extends Component { } } -export const TranslatedStatusBadge = withNamespaces("common")(StatusBadge); +export const TranslatedStatusBadge = withTranslation("common")(StatusBadge); export default () => ( diff --git a/src/components/common/__tests__/Sidebar.test.tsx b/src/components/common/__tests__/Sidebar.test.tsx index 4caa1a1..283d44a 100644 --- a/src/components/common/__tests__/Sidebar.test.tsx +++ b/src/components/common/__tests__/Sidebar.test.tsx @@ -184,7 +184,9 @@ it("renders the NavList in the sidebar", () => { }; const location = {} as Location; - const wrapper = shallow(); + const wrapper = shallow() + .dive() + .dive(); const props = wrapper.find(NavList).props(); expect(props.items).toEqual([item]); diff --git a/src/components/dashboard/ClientsGraph.tsx b/src/components/dashboard/ClientsGraph.tsx index dccaade..dced7d7 100644 --- a/src/components/dashboard/ClientsGraph.tsx +++ b/src/components/dashboard/ClientsGraph.tsx @@ -11,7 +11,7 @@ import React, { Component, RefObject } from "react"; import ReactDOM from "react-dom"; import { Line } from "react-chartjs-2"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { getIntervalForRange, padNumber } from "../../util/graphUtils"; import api from "../../util/api"; import ChartTooltip from "./ChartTooltip"; @@ -30,10 +30,10 @@ export interface ClientsGraphProps { datasets: Array; } -class ClientsGraph extends Component { +class ClientsGraph extends Component { private readonly graphRef: RefObject; - constructor(props: ClientsGraphProps & WithNamespaces) { + constructor(props: ClientsGraphProps & WithTranslation) { super(props); this.graphRef = React.createRef(); } @@ -232,7 +232,7 @@ export const loadingProps: ClientsGraphProps = { datasets: [] }; -export const TranslatedClientsGraph = withNamespaces([ +export const TranslatedClientsGraph = withTranslation([ "dashboard", "time-ranges" ])(ClientsGraph); diff --git a/src/components/dashboard/QueriesGraph.tsx b/src/components/dashboard/QueriesGraph.tsx index 41c2546..2ff4bc3 100644 --- a/src/components/dashboard/QueriesGraph.tsx +++ b/src/components/dashboard/QueriesGraph.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { getIntervalForRange, padNumber } from "../../util/graphUtils"; import api from "../../util/api"; import { WithAPIData } from "../common/WithAPIData"; @@ -29,7 +29,7 @@ export interface QueriesGraphProps { blocked_over_time: Array; } -class QueriesGraph extends Component { +class QueriesGraph extends Component { render() { const { t } = this.props; @@ -210,7 +210,7 @@ export const loadingProps: QueriesGraphProps = { blocked_over_time: [] }; -export const TranslatedQueriesGraph = withNamespaces([ +export const TranslatedQueriesGraph = withTranslation([ "dashboard", "time-ranges" ])(QueriesGraph); diff --git a/src/components/dashboard/QueryTypesChart.tsx b/src/components/dashboard/QueryTypesChart.tsx index 61f75a1..bb947be 100644 --- a/src/components/dashboard/QueryTypesChart.tsx +++ b/src/components/dashboard/QueryTypesChart.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import GenericDoughnutChart from "./GenericDoughnutChart"; import { TimeRangeContext } from "../common/context/TimeRangeContext"; @@ -17,7 +17,7 @@ import { TimeRangeContext } from "../common/context/TimeRangeContext"; const QueryTypesChart = ({ t, apiCall -}: WithNamespaces & { apiCall: () => Promise> }) => ( +}: WithTranslation & { apiCall: () => Promise> }) => ( ); -export const QueryTypesChartContainer = (props: WithNamespaces) => ( +export const QueryTypesChartContainer = (props: WithTranslation) => ( {context => ( ( ); -export default withNamespaces("dashboard")(QueryTypesChartContainer); +export default withTranslation("dashboard")(QueryTypesChartContainer); diff --git a/src/components/dashboard/SummaryStats.tsx b/src/components/dashboard/SummaryStats.tsx index abb3634..43b186e 100644 --- a/src/components/dashboard/SummaryStats.tsx +++ b/src/components/dashboard/SummaryStats.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component, Fragment } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { WithAPIData } from "../common/WithAPIData"; import api from "../../util/api"; import { TimeRangeContext } from "../common/context/TimeRangeContext"; @@ -22,7 +22,7 @@ export interface SummaryStatsProps { uniqueClients: number; } -class SummaryStats extends Component { +class SummaryStats extends Component { render() { const { t } = this.props; @@ -128,7 +128,7 @@ export const initialProps: SummaryStatsProps = { uniqueClients: 0 }; -export const TranslatedSummaryStats = withNamespaces(["common", "dashboard"])( +export const TranslatedSummaryStats = withTranslation(["common", "dashboard"])( SummaryStats ); diff --git a/src/components/dashboard/TimeRangeSelector.tsx b/src/components/dashboard/TimeRangeSelector.tsx index d69bd7a..51d0777 100644 --- a/src/components/dashboard/TimeRangeSelector.tsx +++ b/src/components/dashboard/TimeRangeSelector.tsx @@ -8,7 +8,7 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React, { Fragment } from "react"; +import React, { Fragment, Suspense } from "react"; import DateRangePicker from "react-bootstrap-daterangepicker"; import { Button } from "reactstrap"; import { @@ -16,7 +16,7 @@ import { TimeRangeContext } from "../common/context/TimeRangeContext"; import "bootstrap-daterangepicker/daterangepicker.css"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { dateRanges } from "../../util/dateRanges"; export interface TimeRangeSelectorProps { @@ -49,7 +49,7 @@ export interface TimeRangeSelectorProps { * @param props The selector props */ const renderLabel = ( - props: TimeRangeSelectorProps & WithNamespaces + props: TimeRangeSelectorProps & WithTranslation ): string | null => { const { t } = props; @@ -77,7 +77,7 @@ const renderLabel = ( * predefined, or time range if custom) */ export const TimeRangeSelector = ( - props: TimeRangeSelectorProps & WithNamespaces + props: TimeRangeSelectorProps & WithTranslation ) => { const { range, onSelect, t } = props; @@ -125,19 +125,21 @@ export const TimeRangeSelector = ( ); }; -export const TranslatedTimeRangeSelector = withNamespaces("time-ranges")( +export const TranslatedTimeRangeSelector = withTranslation("time-ranges")( TimeRangeSelector ); export const TimeRangeSelectorContainer = ({ size }: { size?: string }) => ( {context => ( - + + + )} ); diff --git a/src/components/dashboard/TopBlockedClients.tsx b/src/components/dashboard/TopBlockedClients.tsx index ecf3949..0413c6f 100644 --- a/src/components/dashboard/TopBlockedClients.tsx +++ b/src/components/dashboard/TopBlockedClients.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { ReactNode } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import TopTable from "./TopTable"; import i18next from "i18next"; @@ -72,7 +72,7 @@ const TopBlockedClients = ({ apiCall, t, ...props -}: WithNamespaces & { apiCall: () => Promise }) => ( +}: WithTranslation & { apiCall: () => Promise }) => ( ); -const TopBlockedClientsContainer = (props: WithNamespaces) => ( +const TopBlockedClientsContainer = (props: WithTranslation) => ( {context => ( ( ); -export default withNamespaces(["common", "dashboard"])( +export default withTranslation(["common", "dashboard"])( TopBlockedClientsContainer ); diff --git a/src/components/dashboard/TopBlockedDomains.tsx b/src/components/dashboard/TopBlockedDomains.tsx index d658c02..6a63485 100644 --- a/src/components/dashboard/TopBlockedDomains.tsx +++ b/src/components/dashboard/TopBlockedDomains.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import TopTable from "./TopTable"; import i18next from "i18next"; @@ -72,7 +72,7 @@ const TopBlockedDomains = ({ apiCall, t, ...props -}: WithNamespaces & { apiCall: () => Promise }) => ( +}: WithTranslation & { apiCall: () => Promise }) => ( ); -const TopBlockedDomainsContainer = (props: WithNamespaces) => ( +const TopBlockedDomainsContainer = (props: WithTranslation) => ( {context => ( ( ); -export default withNamespaces(["common", "dashboard"])( +export default withTranslation(["common", "dashboard"])( TopBlockedDomainsContainer ); diff --git a/src/components/dashboard/TopClients.tsx b/src/components/dashboard/TopClients.tsx index 03194ad..7c4998a 100644 --- a/src/components/dashboard/TopClients.tsx +++ b/src/components/dashboard/TopClients.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import TopTable from "./TopTable"; import i18next from "i18next"; @@ -70,7 +70,7 @@ const TopClients = ({ apiCall, t, ...props -}: WithNamespaces & { apiCall: () => Promise }) => ( +}: WithTranslation & { apiCall: () => Promise }) => ( ); -const TopClientsContainer = (props: WithNamespaces) => ( +const TopClientsContainer = (props: WithTranslation) => ( {context => ( ( ); -export default withNamespaces(["common", "dashboard"])(TopClientsContainer); +export default withTranslation(["common", "dashboard"])(TopClientsContainer); diff --git a/src/components/dashboard/TopDomains.tsx b/src/components/dashboard/TopDomains.tsx index bc745e5..6ce3fc5 100644 --- a/src/components/dashboard/TopDomains.tsx +++ b/src/components/dashboard/TopDomains.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import TopTable from "./TopTable"; import i18next from "i18next"; @@ -70,7 +70,7 @@ const TopDomains = ({ apiCall, t, ...props -}: WithNamespaces & { apiCall: () => Promise }) => ( +}: WithTranslation & { apiCall: () => Promise }) => ( ); -const TopDomainsContainer = (props: WithNamespaces) => ( +const TopDomainsContainer = (props: WithTranslation) => ( {context => ( ( ); -export default withNamespaces(["common", "dashboard"])(TopDomainsContainer); +export default withTranslation(["common", "dashboard"])(TopDomainsContainer); diff --git a/src/components/dashboard/TopTable.tsx b/src/components/dashboard/TopTable.tsx index 9fd0fa5..64b4e8b 100644 --- a/src/components/dashboard/TopTable.tsx +++ b/src/components/dashboard/TopTable.tsx @@ -10,7 +10,6 @@ import React, { Component, ReactNode } from "react"; import { WithAPIData } from "../common/WithAPIData"; -import { Subtract } from "react-i18next"; export interface TopTableInnerProps { loading: boolean; @@ -87,7 +86,7 @@ export class TopTable extends Component, {}> { } export interface TopTableProps - extends Subtract, { loading: boolean; data: T }> { + extends Omit, "loading" | "data"> { apiCall: () => Promise; initialData: T; apiHandler: (data: D) => T; diff --git a/src/components/dashboard/UpstreamsChart.tsx b/src/components/dashboard/UpstreamsChart.tsx index 60e4c6a..8bfb69f 100644 --- a/src/components/dashboard/UpstreamsChart.tsx +++ b/src/components/dashboard/UpstreamsChart.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import GenericDoughnutChart from "./GenericDoughnutChart"; import { TimeRangeContext } from "../common/context/TimeRangeContext"; @@ -17,7 +17,7 @@ import { TimeRangeContext } from "../common/context/TimeRangeContext"; const UpstreamsChart = ({ t, apiCall -}: WithNamespaces & { apiCall: () => Promise }) => ( +}: WithTranslation & { apiCall: () => Promise }) => ( ); -export const UpstreamsChartContainer = (props: WithNamespaces) => ( +export const UpstreamsChartContainer = (props: WithTranslation) => ( {context => ( ( ); -export default withNamespaces("dashboard")(UpstreamsChartContainer); +export default withTranslation("dashboard")(UpstreamsChartContainer); diff --git a/src/components/list/DomainInput.tsx b/src/components/list/DomainInput.tsx index a000c11..dbc1a5b 100644 --- a/src/components/list/DomainInput.tsx +++ b/src/components/list/DomainInput.tsx @@ -9,10 +9,10 @@ * Please see LICENSE file for your rights under this license. */ import React, { ChangeEvent, Component, FormEvent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; -export interface DomainInputProps extends WithNamespaces { +export interface DomainInputProps extends WithTranslation { placeholder?: string; onEnter: (domain: string) => void; onRefresh: () => void; @@ -92,4 +92,4 @@ class DomainInput extends Component { } } -export default withNamespaces(["common", "lists"])(DomainInput); +export default withTranslation(["common", "lists"])(DomainInput); diff --git a/src/components/list/DomainList.tsx b/src/components/list/DomainList.tsx index 4863803..a9a0224 100644 --- a/src/components/list/DomainList.tsx +++ b/src/components/list/DomainList.tsx @@ -9,12 +9,12 @@ * Please see LICENSE file for your rights under this license. */ import React from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import { Button } from "reactstrap"; import Alert from "../common/Alert"; -export interface DomainListProps extends WithNamespaces { +export interface DomainListProps extends WithTranslation { domains: string[]; onRemove: (domain: string) => void; } @@ -66,4 +66,4 @@ const DomainList = ({ domains, onRemove, t }: DomainListProps) => { return
    {body}
; }; -export default withNamespaces(["common", "lists"])(DomainList); +export default withTranslation(["common", "lists"])(DomainList); diff --git a/src/components/list/ListPage.tsx b/src/components/list/ListPage.tsx index 6450a1d..eca3525 100644 --- a/src/components/list/ListPage.tsx +++ b/src/components/list/ListPage.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import DomainInput from "./DomainInput"; import Alert, { AlertType } from "../common/Alert"; import DomainList from "./DomainList"; @@ -19,7 +19,7 @@ import { makeCancelable } from "../../util/CancelablePromise"; -export interface ListPageProps extends WithNamespaces { +export interface ListPageProps extends WithTranslation { title: string; note?: {} | string; placeholder: string; @@ -178,4 +178,4 @@ export class ListPage extends Component { } } -export default withNamespaces(["common", "lists"])(ListPage); +export default withTranslation(["common", "lists"])(ListPage); diff --git a/src/components/log/QueryLog.tsx b/src/components/log/QueryLog.tsx index f2d5c3d..077c352 100644 --- a/src/components/log/QueryLog.tsx +++ b/src/components/log/QueryLog.tsx @@ -17,7 +17,7 @@ import ReactTable, { } from "react-table"; import i18n from "i18next"; import i18next from "i18next"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import debounce from "lodash.debounce"; import moment from "moment"; import { padNumber } from "../../util/graphUtils"; @@ -58,7 +58,7 @@ const getDefaultRange = (t: i18next.TFunction): TimeRange => { }; }; -class QueryLog extends Component { +class QueryLog extends Component { private updateHandler: null | CancelablePromise = null; state: QueryLogState = { @@ -70,7 +70,7 @@ class QueryLog extends Component { filters: [] }; - constructor(props: WithNamespaces) { + constructor(props: WithTranslation) { super(props); const { t } = this.props; @@ -545,4 +545,6 @@ const columns = (t: i18next.TFunction) => [ } ]; -export default withNamespaces(["common", "query-log", "time-ranges"])(QueryLog); +export default withTranslation(["common", "query-log", "time-ranges"])( + QueryLog +); diff --git a/src/components/login/ForgotPassword.tsx b/src/components/login/ForgotPassword.tsx index cfec0f2..401580f 100644 --- a/src/components/login/ForgotPassword.tsx +++ b/src/components/login/ForgotPassword.tsx @@ -9,9 +9,9 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; -export interface ForgotPasswordProps extends WithNamespaces { +export interface ForgotPasswordProps extends WithTranslation { error: boolean; } @@ -91,4 +91,4 @@ class ForgotPassword extends Component< } } -export default withNamespaces("login")(ForgotPassword); +export default withTranslation("login")(ForgotPassword); diff --git a/src/components/settings/DHCPInfo.tsx b/src/components/settings/DHCPInfo.tsx index 4a5678a..e9673b4 100644 --- a/src/components/settings/DHCPInfo.tsx +++ b/src/components/settings/DHCPInfo.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { ChangeEvent, Component, FormEvent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { CancelablePromise, ignoreCancel, @@ -37,7 +37,7 @@ export interface DHCPInfoState { settings: ApiDhcpSettings; } -class DHCPInfo extends Component { +class DHCPInfo extends Component { state: DHCPInfoState = { alertMessage: "", alertType: "info", @@ -332,4 +332,4 @@ class DHCPInfo extends Component { } } -export default withNamespaces(["common", "settings", "api-errors"])(DHCPInfo); +export default withTranslation(["common", "settings", "api-errors"])(DHCPInfo); diff --git a/src/components/settings/DNSInfo.tsx b/src/components/settings/DNSInfo.tsx index a6ca83e..d6886e6 100644 --- a/src/components/settings/DNSInfo.tsx +++ b/src/components/settings/DNSInfo.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component, FormEvent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { CancelablePromise, ignoreCancel, @@ -35,7 +35,7 @@ export interface DNSInfoState { options: DnsOptionsObject; } -class DNSInfo extends Component { +class DNSInfo extends Component { state: DNSInfoState = { alertMessage: "", alertType: "info", @@ -252,4 +252,4 @@ class DNSInfo extends Component { } } -export default withNamespaces(["common", "settings"])(DNSInfo); +export default withTranslation(["common", "settings"])(DNSInfo); diff --git a/src/components/settings/DnsListNewItem.tsx b/src/components/settings/DnsListNewItem.tsx index 7188878..3343947 100644 --- a/src/components/settings/DnsListNewItem.tsx +++ b/src/components/settings/DnsListNewItem.tsx @@ -11,7 +11,7 @@ import React, { Component, RefObject } from "react"; import { Button, InputGroup, InputGroupAddon, ListGroupItem } from "reactstrap"; import { Typeahead } from "react-bootstrap-typeahead"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { PreconfiguredUpstreamOption, preconfiguredUpstreamOptions @@ -33,7 +33,7 @@ export interface DnsListNewItemState { * a list of preconfigured upstreams, or custom servers can be input. */ class DnsListNewItem extends Component< - DnsListNewItemProps & WithNamespaces, + DnsListNewItemProps & WithTranslation, DnsListNewItemState > { state: DnsListNewItemState = { @@ -43,7 +43,7 @@ class DnsListNewItem extends Component< private readonly typeahead: RefObject; - constructor(props: DnsListNewItemProps & WithNamespaces) { + constructor(props: DnsListNewItemProps & WithTranslation) { super(props); this.typeahead = React.createRef(); } @@ -105,4 +105,4 @@ class DnsListNewItem extends Component< } } -export default withNamespaces("settings")(DnsListNewItem); +export default withTranslation("settings")(DnsListNewItem); diff --git a/src/components/settings/FTLInfo.tsx b/src/components/settings/FTLInfo.tsx index 65726b6..f4c4b49 100644 --- a/src/components/settings/FTLInfo.tsx +++ b/src/components/settings/FTLInfo.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import { WithAPIData } from "../common/WithAPIData"; @@ -19,7 +19,7 @@ export interface FTLInfoProps { sqliteVersion: string; } -class FTLInfo extends Component { +class FTLInfo extends Component { render() { const { t } = this.props; @@ -47,7 +47,7 @@ export const initialData = { sqliteVersion: "" }; -export const TranslatedFTLInfo = withNamespaces(["settings"])(FTLInfo); +export const TranslatedFTLInfo = withTranslation(["settings"])(FTLInfo); export default (props: any) => ( { export const transformData = ( data: ApiNetworkSettings -): Subtract => ({ +): Omit => ({ interface: data.interface, ipv4Address: data.ipv4_address, ipv6Address: data.ipv6_address, @@ -100,7 +100,7 @@ export const initialData = () => ({ hostname: "" }); -export const TranslatedNetworkInfo = withNamespaces(["common", "settings"])( +export const TranslatedNetworkInfo = withTranslation(["common", "settings"])( NetworkInfo ); diff --git a/src/components/settings/PreferenceSettings.tsx b/src/components/settings/PreferenceSettings.tsx index 4a6d242..cc63881 100644 --- a/src/components/settings/PreferenceSettings.tsx +++ b/src/components/settings/PreferenceSettings.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { ChangeEvent, Component, FormEvent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { CancelablePromise, ignoreCancel, @@ -37,7 +37,7 @@ export interface PreferenceSettingsState { } class PreferenceSettings extends Component< - PreferenceSettingsProps & WithNamespaces, + PreferenceSettingsProps & WithTranslation, PreferenceSettingsState > { state: PreferenceSettingsState = { @@ -236,7 +236,7 @@ class PreferenceSettings extends Component< } } -const TranslatedPreferenceSettings = withNamespaces([ +const TranslatedPreferenceSettings = withTranslation([ "common", "settings", "api-errors", diff --git a/src/components/settings/VersionCard.tsx b/src/components/settings/VersionCard.tsx index 85acc64..395fad2 100644 --- a/src/components/settings/VersionCard.tsx +++ b/src/components/settings/VersionCard.tsx @@ -9,10 +9,10 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { Collapse } from "reactstrap"; -export interface VersionCardProps extends WithNamespaces { +export interface VersionCardProps extends WithTranslation { branch: string; hash: string; name: string; @@ -79,4 +79,4 @@ class VersionCard extends Component { } } -export default withNamespaces(["common", "settings"])(VersionCard); +export default withTranslation(["common", "settings"])(VersionCard); diff --git a/src/components/settings/VersionInfo.tsx b/src/components/settings/VersionInfo.tsx index b57c767..a361203 100644 --- a/src/components/settings/VersionInfo.tsx +++ b/src/components/settings/VersionInfo.tsx @@ -9,12 +9,12 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../../util/api"; import VersionCard from "./VersionCard"; import { WithAPIData } from "../common/WithAPIData"; -class VersionInfo extends Component { +class VersionInfo extends Component { render() { const { t } = this.props; @@ -84,7 +84,7 @@ export const initialData: ApiVersions = { } }; -export const TranslatedVersionInfo = withNamespaces(["common"])(VersionInfo); +export const TranslatedVersionInfo = withTranslation(["common"])(VersionInfo); export default (props: any) => ( { it("disables inputs only when DHCP is not enabled", async () => { fetchMock.mock(endpoint, { body: fakeData }); - const wrapper: ShallowWrapper = shallow( + const wrapper: ShallowWrapper = shallow( ); @@ -75,7 +75,7 @@ it("disables the apply button when processing setting update", async () => { fetchMock.get(endpoint, { body: fakeData }); fetchMock.put(endpoint, { body: { status: "success" } }); - const wrapper: ShallowWrapper = shallow( + const wrapper: ShallowWrapper = shallow( ); @@ -94,7 +94,7 @@ it("sends the correct data to the API when apply is clicked", async () => { fetchMock.get(endpoint, { body: fakeData }); fetchMock.put(endpoint, { body: { status: "success" } }); - const wrapper: ShallowWrapper = shallow( + const wrapper: ShallowWrapper = shallow( ); diff --git a/src/containers/Full.tsx b/src/containers/Full.tsx index 0457be3..461801f 100644 --- a/src/containers/Full.tsx +++ b/src/containers/Full.tsx @@ -8,7 +8,7 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -import React, { ComponentType, ReactNode } from "react"; +import React, { ComponentType, ReactNode, Suspense } from "react"; import { Redirect, Route, Switch } from "react-router-dom"; import Header, { mobileSidebarHide } from "../components/common/Header"; import Sidebar from "../components/common/Sidebar"; @@ -35,10 +35,12 @@ export default (props: any) => (
- - - {nav.map(createRoute)} - + + + + {nav.map(createRoute)} + +
@@ -54,7 +56,7 @@ export default (props: any) => ( * @param routeData the route data (see routes.tsx) */ const createRoute = (routeData: RouteData): ReactNode => { - if ((routeData as RouteCustomItem).fakeRoute === true) { + if ((routeData as RouteCustomItem).fakeRoute) { return; } diff --git a/src/setupTests.tsx b/src/setupTests.tsx index 73e537e..1efe8e4 100644 --- a/src/setupTests.tsx +++ b/src/setupTests.tsx @@ -24,8 +24,8 @@ global.t = ((key: string) => key) as i18next.TFunction; // Mock out react-i18next jest.mock("react-i18next", () => ({ - // This mock makes sure any components using the withNamespaces HoC receive the t function as a prop - withNamespaces: () => (component: any) => { + // This mock makes sure any components using the withTranslation HoC receive the t function as a prop + withTranslation: () => (component: any) => { component.defaultProps = { ...component.defaultProps, t: global.t diff --git a/src/util/__tests__/i18n.test.tsx b/src/util/__tests__/i18n.test.tsx index ab58f4f..95266ee 100644 --- a/src/util/__tests__/i18n.test.tsx +++ b/src/util/__tests__/i18n.test.tsx @@ -14,7 +14,7 @@ import { setupI18n } from "../i18n"; // testing. // https://github.com/i18next/react-i18next/issues/434 jest.mock("react-i18next", () => ({ - reactI18nextModule: { + initReactI18next: { type: "3rdParty", init: () => {} } diff --git a/src/util/i18n.tsx b/src/util/i18n.tsx index 89cf31c..c1ca1a6 100644 --- a/src/util/i18n.tsx +++ b/src/util/i18n.tsx @@ -11,7 +11,7 @@ import i18n from "i18next"; import XHR from "i18next-xhr-backend"; import LanguageDetector from "i18next-browser-languagedetector"; -import { reactI18nextModule } from "react-i18next"; +import { initReactI18next } from "react-i18next"; import config from "../config"; import languages from "../languages.json"; @@ -24,7 +24,7 @@ export function setupI18n(ajax?: any) { return i18n .use(XHR) .use(LanguageDetector) - .use(reactI18nextModule) + .use(initReactI18next) .init({ fallbackLng: "en", whitelist: languages, @@ -53,10 +53,6 @@ export function setupI18n(ajax?: any) { backend: { loadPath: process.env.PUBLIC_URL + "/i18n/{{lng}}/{{ns}}.json", ajax - }, - react: { - // Wait until translations are loaded before rendering - wait: true } }); } diff --git a/src/views/Blacklist.tsx b/src/views/Blacklist.tsx index 8a1db81..a2cb8b7 100644 --- a/src/views/Blacklist.tsx +++ b/src/views/Blacklist.tsx @@ -9,12 +9,12 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import api from "../util/api"; import ListPage from "../components/list/ListPage"; import { isValidHostname } from "../util/validate"; -const Blacklist: FunctionComponent = props => { +const Blacklist: FunctionComponent = props => { const { t } = props; return ( @@ -31,4 +31,4 @@ const Blacklist: FunctionComponent = props => { ); }; -export default withNamespaces(["location", "lists"])(Blacklist); +export default withTranslation(["location", "lists"])(Blacklist); diff --git a/src/views/Login.tsx b/src/views/Login.tsx index cda4391..1ba70d6 100644 --- a/src/views/Login.tsx +++ b/src/views/Login.tsx @@ -15,11 +15,11 @@ import api from "../util/api"; import logo from "../img/logo.svg"; import { routes } from "../routes"; import ForgotPassword from "../components/login/ForgotPassword"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import config from "../config"; import { History, LocationDescriptorObject } from "history"; -export interface LoginProps extends WithNamespaces { +export interface LoginProps extends WithTranslation { location: LocationDescriptorObject<{ from: Location }>; history: History; } @@ -176,4 +176,4 @@ class Login extends Component { } } -export default withNamespaces(["login", "location"])(Login); +export default withTranslation(["login", "location"])(Login); diff --git a/src/views/Networking.tsx b/src/views/Networking.tsx index 4783bfb..33a0b1d 100644 --- a/src/views/Networking.tsx +++ b/src/views/Networking.tsx @@ -9,7 +9,7 @@ * Please see LICENSE file for your rights under this license. */ import React, { Component, ReactNode } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import { Nav, NavItem, NavLink, TabContent, TabPane } from "reactstrap"; import DHCPInfo from "../components/settings/DHCPInfo"; import DNSInfo from "../components/settings/DNSInfo"; @@ -20,7 +20,7 @@ export interface NetworkingState { activeTab: string; } -class Networking extends Component { +class Networking extends Component { state = { activeTab: "network" }; @@ -89,4 +89,4 @@ class Networking extends Component { } } -export default withNamespaces(["common", "settings"])(Networking); +export default withTranslation(["common", "settings"])(Networking); diff --git a/src/views/Regexlist.tsx b/src/views/Regexlist.tsx index 7329179..0d40d3b 100644 --- a/src/views/Regexlist.tsx +++ b/src/views/Regexlist.tsx @@ -9,12 +9,12 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; import { isValidRegex } from "../util/validate"; -const Regexlist: FunctionComponent = props => { +const Regexlist: FunctionComponent = props => { const { t } = props; return ( @@ -31,4 +31,4 @@ const Regexlist: FunctionComponent = props => { ); }; -export default withNamespaces(["location", "lists"])(Regexlist); +export default withTranslation(["location", "lists"])(Regexlist); diff --git a/src/views/Whitelist.tsx b/src/views/Whitelist.tsx index b9a28d9..d1b9d6e 100644 --- a/src/views/Whitelist.tsx +++ b/src/views/Whitelist.tsx @@ -9,12 +9,12 @@ * Please see LICENSE file for your rights under this license. */ import React, { FunctionComponent } from "react"; -import { WithNamespaces, withNamespaces } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import ListPage from "../components/list/ListPage"; import api from "../util/api"; import { isValidHostname } from "../util/validate"; -const Whitelist: FunctionComponent = props => { +const Whitelist: FunctionComponent = props => { const { t } = props; return ( @@ -31,4 +31,4 @@ const Whitelist: FunctionComponent = props => { ); }; -export default withNamespaces(["location", "lists"])(Whitelist); +export default withTranslation(["location", "lists"])(Whitelist);