From d6cff6a4da76f83c2b5d2c66a7ff2ac6fa1d01df Mon Sep 17 00:00:00 2001 From: Joijanae Laws Date: Thu, 3 Oct 2024 20:00:22 -0500 Subject: [PATCH 1/5] Standardize Translation Method --- src/client/app/components/AreaUnitSelectComponent.tsx | 4 ++-- src/client/app/components/BarChartComponent.tsx | 3 ++- src/client/app/components/BarControlsComponent.tsx | 3 ++- src/client/app/components/ChartLinkComponent.tsx | 3 ++- src/client/app/components/ChartSelectComponent.tsx | 3 ++- src/client/app/components/CompareControlsComponent.tsx | 3 ++- src/client/app/components/ConfirmActionModalComponent.tsx | 4 ++-- src/client/app/components/DateRangeComponent.tsx | 3 ++- src/client/app/components/ErrorBarComponent.tsx | 3 ++- src/client/app/components/FormFileUploaderComponent.tsx | 4 ++-- src/client/app/components/GraphicRateMenuComponent.tsx | 3 ++- src/client/app/components/HeaderButtonsComponent.tsx | 3 ++- src/client/app/components/LineChartComponent.tsx | 3 ++- src/client/app/components/LoginComponent.tsx | 3 ++- src/client/app/components/MapChartComponent.tsx | 4 ++-- src/client/app/components/MapControlsComponent.tsx | 3 ++- src/client/app/components/MeterAndGroupSelectComponent.tsx | 3 ++- src/client/app/components/MoreOptionsComponent.tsx | 3 ++- src/client/app/components/RadarChartComponent.tsx | 3 ++- src/client/app/components/ReadingsPerDaySelectComponent.tsx | 3 ++- src/client/app/components/ThreeDComponent.tsx | 5 ++++- src/client/app/components/ThreeDPillComponent.tsx | 3 ++- src/client/app/components/TimeZoneSelect.tsx | 3 ++- src/client/app/components/TooltipHelpComponent.tsx | 4 ++-- src/client/app/components/UnitSelectComponent.tsx | 3 ++- src/client/app/components/UnsavedWarningComponent.tsx | 3 ++- src/client/app/components/admin/PreferencesComponent.tsx | 3 ++- .../app/components/admin/users/CreateUserModalComponent.tsx | 4 ++-- .../app/components/admin/users/EditUserModalComponent.tsx | 4 ++-- src/client/app/components/admin/users/UserViewComponent.tsx | 3 ++- .../app/components/admin/users/UsersDetailComponent.tsx | 3 ++- .../app/components/conversion/ConversionViewComponent.tsx | 3 ++- .../components/conversion/CreateConversionModalComponent.tsx | 3 ++- .../components/conversion/EditConversionModalComponent.tsx | 3 ++- src/client/app/components/csv/MetersCSVUploadComponent.tsx | 3 ++- src/client/app/components/csv/ReadingsCSVUploadComponent.tsx | 4 ++-- .../app/components/groups/CreateGroupModalComponent.tsx | 3 ++- src/client/app/components/groups/EditGroupModalComponent.tsx | 3 ++- src/client/app/components/groups/GroupViewComponent.tsx | 3 ++- .../app/components/meters/CreateMeterModalComponent.tsx | 3 ++- src/client/app/components/meters/EditMeterModalComponent.tsx | 3 ++- src/client/app/components/meters/MeterViewComponent.tsx | 3 ++- src/client/app/components/router/ErrorComponent.tsx | 3 ++- src/client/app/components/router/InitializingComponent.tsx | 3 ++- src/client/app/components/unit/UnitViewComponent.tsx | 3 ++- src/client/app/containers/CompareChartContainer.ts | 3 ++- src/client/app/containers/MapChartContainer.ts | 3 ++- .../containers/maps/MapCalibrationInfoDisplayContainer.ts | 3 ++- src/client/app/redux/actions/conversions.ts | 3 ++- src/client/app/redux/actions/map.ts | 5 ++++- .../app/redux/middleware/unauthorizedAccesMiddleware.ts | 3 ++- src/client/app/redux/selectors/adminSelectors.ts | 4 ++-- src/client/app/redux/selectors/lineChartSelectors.ts | 3 ++- src/client/app/redux/thunks/exportThunk.ts | 3 ++- src/client/app/utils/calculateCompare.ts | 4 +++- src/client/app/utils/calibration.ts | 3 ++- src/client/app/utils/graphics.ts | 5 +++-- src/client/app/utils/input.ts | 3 ++- 58 files changed, 122 insertions(+), 68 deletions(-) diff --git a/src/client/app/components/AreaUnitSelectComponent.tsx b/src/client/app/components/AreaUnitSelectComponent.tsx index a42850e1e..739e6fb26 100644 --- a/src/client/app/components/AreaUnitSelectComponent.tsx +++ b/src/client/app/components/AreaUnitSelectComponent.tsx @@ -11,7 +11,7 @@ import { selectUnitDataById } from '../redux/api/unitsApi'; import { StringSelectOption } from '../types/items'; import { UnitRepresentType } from '../types/redux/units'; import { AreaUnitType } from '../utils/getAreaUnitConversion'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** @@ -20,7 +20,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; */ export default function AreaUnitSelectComponent() { const dispatch = useAppDispatch(); - + const translate = useTranslate(); const graphState = useAppSelector(selectGraphState); const unitDataById = useAppSelector(selectUnitDataById); diff --git a/src/client/app/components/BarChartComponent.tsx b/src/client/app/components/BarChartComponent.tsx index 755509308..e3a7ed65c 100644 --- a/src/client/app/components/BarChartComponent.tsx +++ b/src/client/app/components/BarChartComponent.tsx @@ -17,7 +17,7 @@ import { selectBarUnitLabel, selectIsRaw } from '../redux/selectors/plotlyDataSe import { selectSelectedLanguage } from '../redux/slices/appStateSlice'; import { selectBarStacking } from '../redux/slices/graphSlice'; import Locales from '../types/locales'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import SpinnerComponent from './SpinnerComponent'; /** @@ -27,6 +27,7 @@ import SpinnerComponent from './SpinnerComponent'; * @returns Plotly BarChart */ export default function BarChartComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const { barMeterDeps, barGroupDeps } = useAppSelector(selectPlotlyBarDeps); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectBarChartQueryArgs); diff --git a/src/client/app/components/BarControlsComponent.tsx b/src/client/app/components/BarControlsComponent.tsx index 03e858d11..ead20b67c 100644 --- a/src/client/app/components/BarControlsComponent.tsx +++ b/src/client/app/components/BarControlsComponent.tsx @@ -8,13 +8,14 @@ import { FormattedMessage } from 'react-intl'; import { FormFeedback, FormGroup, Input, Label } from 'reactstrap'; import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { graphSlice, selectBarStacking, selectBarWidthDays } from '../redux/slices/graphSlice'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** * @returns controls for the Options Ui page. */ export default function BarControlsComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // The min/max days allowed for user selection diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 8eb0987e2..6de7aabae 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -11,13 +11,14 @@ import { selectChartLink } from '../redux/selectors/uiSelectors'; import { selectChartLinkHideOptions, setChartLinkOptionsVisibility } from '../redux/slices/appStateSlice'; import { selectSelectedGroups, selectSelectedMeters } from '../redux/slices/graphSlice'; import { showErrorNotification, showInfoNotification } from '../utils/notifications'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** * @returns chartLinkComponent */ export default function ChartLinkComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const [linkTextVisible, setLinkTextVisible] = React.useState(false); const linkText = useAppSelector(selectChartLink); diff --git a/src/client/app/components/ChartSelectComponent.tsx b/src/client/app/components/ChartSelectComponent.tsx index 9625734ae..494bae623 100644 --- a/src/client/app/components/ChartSelectComponent.tsx +++ b/src/client/app/components/ChartSelectComponent.tsx @@ -13,7 +13,7 @@ import { graphSlice, selectChartToRender } from '../redux/slices/graphSlice'; import { SelectOption } from '../types/items'; import { ChartTypes } from '../types/redux/graph'; import { State } from '../types/redux/state'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** @@ -21,6 +21,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Chart select element */ export default function ChartSelectComponent() { + const translate = useTranslate(); const currentChartToRender = useAppSelector(selectChartToRender); const dispatch = useAppDispatch(); const [expand, setExpand] = useState(false); diff --git a/src/client/app/components/CompareControlsComponent.tsx b/src/client/app/components/CompareControlsComponent.tsx index d990852cd..5b9cd3447 100644 --- a/src/client/app/components/CompareControlsComponent.tsx +++ b/src/client/app/components/CompareControlsComponent.tsx @@ -8,13 +8,14 @@ import { Button, ButtonGroup, Dropdown, DropdownItem, DropdownMenu, DropdownTogg import { graphSlice, selectComparePeriod, selectSortingOrder } from '../redux/slices/graphSlice'; import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { ComparePeriod, SortingOrder } from '../utils/calculateCompare'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** * @returns controls for the compare page */ export default function CompareControlsComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const comparePeriod = useAppSelector(selectComparePeriod); const compareSortingOrder = useAppSelector(selectSortingOrder); diff --git a/src/client/app/components/ConfirmActionModalComponent.tsx b/src/client/app/components/ConfirmActionModalComponent.tsx index e3730aa62..9f15d58b7 100644 --- a/src/client/app/components/ConfirmActionModalComponent.tsx +++ b/src/client/app/components/ConfirmActionModalComponent.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import '../styles/modal.css'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; interface ConfirmActionModalComponentProps { @@ -41,7 +41,7 @@ interface ConfirmActionModalComponentProps { * @returns A modal component that executes the actionFunction on confirmation and handleClose on rejection. */ export default function ConfirmActionModalComponent(props: ConfirmActionModalComponentProps) { - + const translate = useTranslate(); const handleClose = () => { props.handleClose(); }; diff --git a/src/client/app/components/DateRangeComponent.tsx b/src/client/app/components/DateRangeComponent.tsx index 22f7846ed..033b311e3 100644 --- a/src/client/app/components/DateRangeComponent.tsx +++ b/src/client/app/components/DateRangeComponent.tsx @@ -13,7 +13,7 @@ import { changeSliderRange, selectQueryTimeInterval, updateTimeInterval, selectC import '../styles/DateRangeCustom.css'; import { Dispatch } from '../types/redux/actions'; import { dateRangeToTimeInterval, timeIntervalToDateRange } from '../utils/dateRangeCompatibility'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; import { ChartTypes } from '../types/redux/graph'; @@ -22,6 +22,7 @@ import { ChartTypes } from '../types/redux/graph'; * @returns Date Range Calendar Picker */ export default function DateRangeComponent() { + const translate = useTranslate(); const dispatch: Dispatch = useAppDispatch(); const queryTimeInterval = useAppSelector(selectQueryTimeInterval); const locale = useAppSelector(selectSelectedLanguage); diff --git a/src/client/app/components/ErrorBarComponent.tsx b/src/client/app/components/ErrorBarComponent.tsx index c8116ed3e..957adb04b 100644 --- a/src/client/app/components/ErrorBarComponent.tsx +++ b/src/client/app/components/ErrorBarComponent.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { graphSlice, selectShowMinMax } from '../redux/slices/graphSlice'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** @@ -13,6 +13,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Error Bar checkbox with tooltip and label */ export default function ErrorBarComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const showMinMax = useAppSelector(selectShowMinMax); diff --git a/src/client/app/components/FormFileUploaderComponent.tsx b/src/client/app/components/FormFileUploaderComponent.tsx index be8032ee6..714001f63 100644 --- a/src/client/app/components/FormFileUploaderComponent.tsx +++ b/src/client/app/components/FormFileUploaderComponent.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { Col, Input, FormGroup, Label } from 'reactstrap'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; interface FileUploader { isInvalid: boolean; @@ -17,7 +17,7 @@ interface FileUploader { * @returns File uploader element */ export default function FileUploaderComponent(props: FileUploader) { - + const translate = useTranslate(); const handleFileChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0] || null; props.onFileChange(file); diff --git a/src/client/app/components/GraphicRateMenuComponent.tsx b/src/client/app/components/GraphicRateMenuComponent.tsx index 163d51965..febe41352 100644 --- a/src/client/app/components/GraphicRateMenuComponent.tsx +++ b/src/client/app/components/GraphicRateMenuComponent.tsx @@ -11,7 +11,7 @@ import { graphSlice, selectGraphState } from '../redux/slices/graphSlice'; import { SelectOption } from '../types/items'; import { ChartTypes, LineGraphRate, LineGraphRates } from '../types/redux/graph'; import { UnitRepresentType } from '../types/redux/units'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** @@ -19,6 +19,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Rate selection element */ export default function GraphicRateMenuComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // Graph state diff --git a/src/client/app/components/HeaderButtonsComponent.tsx b/src/client/app/components/HeaderButtonsComponent.tsx index a48b18f56..58f41e53e 100644 --- a/src/client/app/components/HeaderButtonsComponent.tsx +++ b/src/client/app/components/HeaderButtonsComponent.tsx @@ -16,7 +16,7 @@ import { selectHelpUrl } from '../redux/slices/adminSlice'; import { selectOptionsVisibility, toggleOptionsVisibility } from '../redux/slices/appStateSlice'; import { selectHasRolePermissions, selectIsAdmin, selectIsLoggedIn } from '../redux/slices/currentUserSlice'; import { UserRole } from '../types/items'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import LanguageSelectorComponent from './LanguageSelectorComponent'; import TooltipMarkerComponent from './TooltipMarkerComponent'; @@ -25,6 +25,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Header buttons element */ export default function HeaderButtonsComponent() { + const translate = useTranslate(); const [logout] = authApi.useLogoutMutation(); const dispatch = useAppDispatch(); // Get the current page so know which one should not be shown in menu. diff --git a/src/client/app/components/LineChartComponent.tsx b/src/client/app/components/LineChartComponent.tsx index f71058629..95c0d294e 100644 --- a/src/client/app/components/LineChartComponent.tsx +++ b/src/client/app/components/LineChartComponent.tsx @@ -16,7 +16,7 @@ import { selectLineChartDeps, selectPlotlyGroupData, selectPlotlyMeterData } fro import { selectLineUnitLabel } from '../redux/selectors/plotlyDataSelectors'; import { selectSelectedLanguage } from '../redux/slices/appStateSlice'; import Locales from '../types/locales'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import SpinnerComponent from './SpinnerComponent'; @@ -24,6 +24,7 @@ import SpinnerComponent from './SpinnerComponent'; * @returns plotlyLine graphic */ export default function LineChartComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // get current data fetching arguments const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectLineChartQueryArgs); diff --git a/src/client/app/components/LoginComponent.tsx b/src/client/app/components/LoginComponent.tsx index 538c03d99..d182fd13d 100644 --- a/src/client/app/components/LoginComponent.tsx +++ b/src/client/app/components/LoginComponent.tsx @@ -9,13 +9,14 @@ import { useNavigate } from 'react-router-dom'; import { Button, Form, FormGroup, Input, Label } from 'reactstrap'; import { authApi } from '../redux/api/authApi'; import { showErrorNotification, showSuccessNotification } from '../utils/notifications'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; /** * @returns The login page for users or admins. */ export default function LoginComponent() { + const translate = useTranslate(); // Local State const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); diff --git a/src/client/app/components/MapChartComponent.tsx b/src/client/app/components/MapChartComponent.tsx index e1a5dde28..baf02d3b4 100644 --- a/src/client/app/components/MapChartComponent.tsx +++ b/src/client/app/components/MapChartComponent.tsx @@ -32,14 +32,14 @@ import { } from '../utils/calibration'; import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion'; import getGraphColor from '../utils/getGraphColor'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import SpinnerComponent from './SpinnerComponent'; /** * @returns map component */ export default function MapChartComponent() { - + const translate = useTranslate(); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectMapChartQueryArgs); const { data: meterReadings, isLoading: meterIsFetching } = readingsApi.useBarQuery(meterArgs, { skip: meterShouldSkip }); const { data: groupData, isLoading: groupIsFetching } = readingsApi.useBarQuery(groupArgs, { skip: groupShouldSkip }); diff --git a/src/client/app/components/MapControlsComponent.tsx b/src/client/app/components/MapControlsComponent.tsx index ac0934d4e..9a3a10ddc 100644 --- a/src/client/app/components/MapControlsComponent.tsx +++ b/src/client/app/components/MapControlsComponent.tsx @@ -8,13 +8,14 @@ import * as React from 'react'; import { Button, ButtonGroup } from 'reactstrap'; import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { selectMapBarWidthDays, updateMapsBarDuration } from '../redux/slices/graphSlice'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import MapChartSelectComponent from './MapChartSelectComponent'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** * @returns Map page controls */ export default function MapControlsComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const barDuration = useAppSelector(selectMapBarWidthDays); diff --git a/src/client/app/components/MeterAndGroupSelectComponent.tsx b/src/client/app/components/MeterAndGroupSelectComponent.tsx index 52d1e9f7d..67f0b8015 100644 --- a/src/client/app/components/MeterAndGroupSelectComponent.tsx +++ b/src/client/app/components/MeterAndGroupSelectComponent.tsx @@ -16,7 +16,7 @@ import { selectMeterGroupSelectData } from '../redux/selectors/uiSelectors'; import { selectChartToRender, updateSelectedMetersOrGroups, updateThreeDMeterOrGroupInfo } from '../redux/slices/graphSlice'; import { GroupedOption, SelectOption } from '../types/items'; import { ChartTypes, MeterOrGroup } from '../types/redux/graph'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; import { selectAnythingFetching } from '../redux/selectors/apiSelectors'; /** @@ -25,6 +25,7 @@ import { selectAnythingFetching } from '../redux/selectors/apiSelectors'; * @returns A React-Select component. */ export default function MeterAndGroupSelectComponent(props: MeterAndGroupSelectProps) { + const translate = useTranslate(); const dispatch = useAppDispatch(); const { meterGroupedOptions, groupsGroupedOptions, allSelectedMeterValues, allSelectedGroupValues } = useAppSelector(selectMeterGroupSelectData); const somethingIsFetching = useAppSelector(selectAnythingFetching); diff --git a/src/client/app/components/MoreOptionsComponent.tsx b/src/client/app/components/MoreOptionsComponent.tsx index 4441d882c..bdc860ab3 100644 --- a/src/client/app/components/MoreOptionsComponent.tsx +++ b/src/client/app/components/MoreOptionsComponent.tsx @@ -15,13 +15,14 @@ import DateRangeComponent from './DateRangeComponent'; import ErrorBarComponent from './ErrorBarComponent'; import ExportComponent from '../components/ExportComponent'; import GraphicRateMenuComponent from './GraphicRateMenuComponent'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; /** * Modal popup control for various graph types * @returns Custom Modal depending on selected graph type */ export default function MoreOptionsComponent() { + const translate = useTranslate(); const chartToRender = useAppSelector(selectChartToRender); const [showModal, setShowModal] = useState(false); const handleShow = () => setShowModal(true); diff --git a/src/client/app/components/RadarChartComponent.tsx b/src/client/app/components/RadarChartComponent.tsx index 37ce9a0b7..3ff51879b 100644 --- a/src/client/app/components/RadarChartComponent.tsx +++ b/src/client/app/components/RadarChartComponent.tsx @@ -22,13 +22,14 @@ import Locales from '../types/locales'; import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion'; import getGraphColor from '../utils/getGraphColor'; import { lineUnitLabel } from '../utils/graphics'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import SpinnerComponent from './SpinnerComponent'; /** * @returns radar plotly component */ export default function RadarChartComponent() { + const translate = useTranslate(); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectRadarChartQueryArgs); const { data: meterReadings, isLoading: meterIsLoading } = readingsApi.useLineQuery(meterArgs, { skip: meterShouldSkip }); const { data: groupData, isLoading: groupIsLoading } = readingsApi.useLineQuery(groupArgs, { skip: groupShouldSkip }); diff --git a/src/client/app/components/ReadingsPerDaySelectComponent.tsx b/src/client/app/components/ReadingsPerDaySelectComponent.tsx index a75d6a513..40a56cbd0 100644 --- a/src/client/app/components/ReadingsPerDaySelectComponent.tsx +++ b/src/client/app/components/ReadingsPerDaySelectComponent.tsx @@ -10,7 +10,7 @@ import { selectThreeDQueryArgs } from '../redux/selectors/chartQuerySelectors'; import { selectReadingsPerDaySelectData } from '../redux/selectors/threeDSelectors'; import { selectThreeDReadingInterval, updateThreeDReadingInterval } from '../redux/slices/graphSlice'; import { ReadingInterval } from '../types/redux/graph'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; /** @@ -18,6 +18,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns A Select menu with Readings per day options. */ export default function ReadingsPerDaySelect() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const readingInterval = useAppSelector(selectThreeDReadingInterval); const { args, shouldSkipQuery } = useAppSelector(selectThreeDQueryArgs); diff --git a/src/client/app/components/ThreeDComponent.tsx b/src/client/app/components/ThreeDComponent.tsx index 658df7415..ba512e23d 100644 --- a/src/client/app/components/ThreeDComponent.tsx +++ b/src/client/app/components/ThreeDComponent.tsx @@ -20,7 +20,7 @@ import { UnitDataById } from '../types/redux/units'; import { isValidThreeDInterval, roundTimeIntervalForFetch } from '../utils/dateRangeCompatibility'; import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion'; import { lineUnitLabel } from '../utils/graphics'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import SpinnerComponent from './SpinnerComponent'; import ThreeDPillComponent from './ThreeDPillComponent'; import Plot from 'react-plotly.js'; @@ -32,6 +32,7 @@ import Locales from '../types/locales'; * @returns 3D Plotly 3D Surface Graph */ export default function ThreeDComponent() { + const translate = useTranslate(); const { args, shouldSkipQuery } = useAppSelector(selectThreeDQueryArgs); const { data, isFetching } = readingsApi.endpoints.threeD.useQuery(args, { skip: shouldSkipQuery }); const meterDataById = useAppSelector(selectMeterDataById); @@ -158,6 +159,7 @@ function formatThreeDData( // Calculate Hover Text, and populate xLabels/yLabels const hoverText = zDataToRender.map((day, i) => day.map((readings, j) => { + const translate = useTranslate(); const startTS = moment.utc(data.xData[j].startTimestamp); const endTS = moment.utc(data.xData[j].endTimestamp); const midpointTS = moment.utc(startTS.clone().add(endTS.clone().diff(startTS) / 2)); @@ -227,6 +229,7 @@ function setHelpLayout(helpText: string = 'Help Text Goes Here', fontSize: numbe * @returns plotly layout object. */ function setThreeDLayout(zLabelText: string = 'Resource Usage', yDataToRender: string[]) { + const translate = useTranslate(); // Convert date strings to JavaScript Date objects and then get dataRange const dateObjects = yDataToRender.map(dateStr => new Date(dateStr)); const dataMin = Math.min(...dateObjects.map(date => date.getTime())); diff --git a/src/client/app/components/ThreeDPillComponent.tsx b/src/client/app/components/ThreeDPillComponent.tsx index a5c7b8ae2..cbc637e7a 100644 --- a/src/client/app/components/ThreeDPillComponent.tsx +++ b/src/client/app/components/ThreeDPillComponent.tsx @@ -10,13 +10,14 @@ import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { MeterOrGroup, MeterOrGroupPill } from '../types/redux/graph'; import { AreaUnitType } from '../utils/getAreaUnitConversion'; import { selectMeterDataById } from '../redux/api/metersApi'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; /** * A component used in the threeD graphics to select a single meter from the currently selected meters and groups. * @returns List of selected groups and meters as reactstrap Pills Badges */ export default function ThreeDPillComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const meterDataById = useAppSelector(selectMeterDataById); const groupDataById = useAppSelector(selectGroupDataById); diff --git a/src/client/app/components/TimeZoneSelect.tsx b/src/client/app/components/TimeZoneSelect.tsx index b8dd891b6..10a740e54 100644 --- a/src/client/app/components/TimeZoneSelect.tsx +++ b/src/client/app/components/TimeZoneSelect.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import Select from 'react-select'; import { TimeZoneOption } from 'types/timezone'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import * as moment from 'moment-timezone'; interface TimeZoneSelectProps { @@ -15,6 +15,7 @@ interface TimeZoneSelectProps { } const TimeZoneSelect: React.FC = ({ current, handleClick }) => { + const translate = useTranslate(); const getTimeZones = () => { const zoneNames = moment.tz.names(); diff --git a/src/client/app/components/TooltipHelpComponent.tsx b/src/client/app/components/TooltipHelpComponent.tsx index 10a56d79a..b7decbf4d 100644 --- a/src/client/app/components/TooltipHelpComponent.tsx +++ b/src/client/app/components/TooltipHelpComponent.tsx @@ -9,7 +9,7 @@ import { selectOEDVersion } from '../redux/api/versionApi'; import { useAppSelector } from '../redux/reduxHooks'; import { selectHelpUrl } from '../redux/slices/adminSlice'; import '../styles/tooltip.css'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; interface TooltipHelpProps { page: string; // Specifies which page the tip is in. @@ -20,7 +20,7 @@ interface TooltipHelpProps { * @returns ToolTipHelpComponent */ export default function TooltipHelpComponent(props: TooltipHelpProps) { - + const translate = useTranslate(); /** * @returns JSX to create the help icons with links */ diff --git a/src/client/app/components/UnitSelectComponent.tsx b/src/client/app/components/UnitSelectComponent.tsx index aee27bdbc..f07e478de 100644 --- a/src/client/app/components/UnitSelectComponent.tsx +++ b/src/client/app/components/UnitSelectComponent.tsx @@ -11,7 +11,7 @@ import { GroupedOption, SelectOption } from '../types/items'; // import { FormattedMessage } from 'react-intl'; import { Badge } from 'reactstrap'; import { graphSlice, selectSelectedUnit } from '../redux/slices/graphSlice'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; import { selectUnitDataById, unitsApi } from '../redux/api/unitsApi'; @@ -19,6 +19,7 @@ import { selectUnitDataById, unitsApi } from '../redux/api/unitsApi'; * @returns A React-Select component for UI Options Panel */ export default function UnitSelectComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const unitSelectOptions = useAppSelector(selectUnitSelectData); const selectedUnitID = useAppSelector(selectSelectedUnit); diff --git a/src/client/app/components/UnsavedWarningComponent.tsx b/src/client/app/components/UnsavedWarningComponent.tsx index 651c94eb4..313a288d9 100644 --- a/src/client/app/components/UnsavedWarningComponent.tsx +++ b/src/client/app/components/UnsavedWarningComponent.tsx @@ -10,7 +10,7 @@ import { useBlocker } from 'react-router-dom'; import { Button, Modal, ModalBody, ModalFooter } from 'reactstrap'; import { LocaleDataKey } from '../translations/data'; import { showErrorNotification, showSuccessNotification } from '../utils/notifications'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; export interface UnsavedWarningProps { changes: any; @@ -25,6 +25,7 @@ export interface UnsavedWarningProps { * @returns Component that prompts before navigating away from current page */ export function UnsavedWarningComponent(props: UnsavedWarningProps) { + const translate = useTranslate(); const { hasUnsavedChanges, submitChanges, changes } = props; const blocker = useBlocker(hasUnsavedChanges); const handleSubmit = async () => { diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index 825c8b758..ffc2717cb 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -13,7 +13,7 @@ import { ChartTypes } from '../../types/redux/graph'; import { LanguageTypes } from '../../types/redux/i18n'; import { AreaUnitType } from '../../utils/getAreaUnitConversion'; import { showErrorNotification, showSuccessNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import TimeZoneSelect from '../TimeZoneSelect'; import { defaultAdminState } from '../../redux/slices/adminSlice'; @@ -23,6 +23,7 @@ import { defaultAdminState } from '../../redux/slices/adminSlice'; * @returns Preferences Component for Administrative use */ export default function PreferencesComponent() { + const translate = useTranslate(); const { data: adminPreferences = defaultAdminState } = preferencesApi.useGetPreferencesQuery(); const [localAdminPref, setLocalAdminPref] = React.useState(cloneDeep(adminPreferences)); const [submitPreferences] = preferencesApi.useSubmitPreferencesMutation(); diff --git a/src/client/app/components/admin/users/CreateUserModalComponent.tsx b/src/client/app/components/admin/users/CreateUserModalComponent.tsx index f2a875b4e..0594c73ff 100644 --- a/src/client/app/components/admin/users/CreateUserModalComponent.tsx +++ b/src/client/app/components/admin/users/CreateUserModalComponent.tsx @@ -11,7 +11,7 @@ import { import { userApi } from '../../../redux/api/userApi'; import { User, UserRole, userDefaults } from '../../../types/items'; import { showErrorNotification, showSuccessNotification } from '../../../utils/notifications'; -import translate from '../../../utils/translate'; +import { useTranslate } from '../../../redux/componentHooks'; import TooltipHelpComponent from '../../TooltipHelpComponent'; import TooltipMarkerComponent from '../../TooltipMarkerComponent'; import { tooltipBaseStyle } from '../../../styles/modalStyle'; @@ -21,7 +21,7 @@ import { tooltipBaseStyle } from '../../../styles/modalStyle'; * @returns CreateUserModal component */ export default function CreateUserModal() { - + const translate = useTranslate(); // create user form state and use the defaults const [userDetails, setUserDetails] = useState(userDefaults); diff --git a/src/client/app/components/admin/users/EditUserModalComponent.tsx b/src/client/app/components/admin/users/EditUserModalComponent.tsx index 2048c2bfc..4568b2704 100644 --- a/src/client/app/components/admin/users/EditUserModalComponent.tsx +++ b/src/client/app/components/admin/users/EditUserModalComponent.tsx @@ -10,7 +10,7 @@ import { useAppSelector } from '../../../redux/reduxHooks'; import { selectCurrentUserProfile } from '../../../redux/slices/currentUserSlice'; import { User, UserRole, userDefaults } from '../../../types/items'; import { showErrorNotification, showSuccessNotification } from '../../../utils/notifications'; -import translate from '../../../utils/translate'; +import { useTranslate } from '../../../redux/componentHooks'; import ConfirmActionModalComponent from '../../ConfirmActionModalComponent'; import TooltipHelpComponent from '../../TooltipHelpComponent'; import TooltipMarkerComponent from '../../TooltipMarkerComponent'; @@ -29,7 +29,7 @@ interface EditUserModalComponentProps { * @returns User edit element */ export default function EditUserModalComponent(props: EditUserModalComponentProps) { - + const translate = useTranslate(); // get current logged in user const currentLoggedInUser = useAppSelector(selectCurrentUserProfile) as User; diff --git a/src/client/app/components/admin/users/UserViewComponent.tsx b/src/client/app/components/admin/users/UserViewComponent.tsx index 24650438f..0420c3032 100644 --- a/src/client/app/components/admin/users/UserViewComponent.tsx +++ b/src/client/app/components/admin/users/UserViewComponent.tsx @@ -8,7 +8,7 @@ import { useState } from 'react'; import { Button } from 'reactstrap'; import '../../../styles/card-page.css'; import { User } from '../../../types/items'; -import translate from '../../../utils/translate'; +import { useTranslate } from '../../../redux/componentHooks'; import EditUserModalComponent from './EditUserModalComponent'; interface UserViewComponentProps { @@ -21,6 +21,7 @@ interface UserViewComponentProps { * @returns User card element */ export default function UserViewComponent(props: UserViewComponentProps) { + const translate = useTranslate(); const [showEditModal, setShowEditModal] = useState(false); const handleShow = () => { diff --git a/src/client/app/components/admin/users/UsersDetailComponent.tsx b/src/client/app/components/admin/users/UsersDetailComponent.tsx index ff5a8742e..c01c382db 100644 --- a/src/client/app/components/admin/users/UsersDetailComponent.tsx +++ b/src/client/app/components/admin/users/UsersDetailComponent.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { Col, Container, Row } from 'reactstrap'; import { stableEmptyUsers, userApi } from '../../../redux/api/userApi'; -import translate from '../../../utils/translate'; +import { useTranslate } from '../../../redux/componentHooks'; import TooltipHelpComponent from '../../TooltipHelpComponent'; import TooltipMarkerComponent from '../../TooltipMarkerComponent'; import CreateUserModalComponent from './CreateUserModalComponent'; @@ -22,6 +22,7 @@ const tooltipStyle = { * @returns User Detail element */ export default function UserDetailComponent() { + const translate = useTranslate(); const { data: users = stableEmptyUsers } = userApi.useGetUsersQuery(); return ( diff --git a/src/client/app/components/conversion/ConversionViewComponent.tsx b/src/client/app/components/conversion/ConversionViewComponent.tsx index 304008f7e..c63642372 100644 --- a/src/client/app/components/conversion/ConversionViewComponent.tsx +++ b/src/client/app/components/conversion/ConversionViewComponent.tsx @@ -12,7 +12,7 @@ import { selectUnitDataById } from '../../redux/api/unitsApi'; import { useAppSelector } from '../../redux/reduxHooks'; import '../../styles/card-page.css'; import { conversionArrow } from '../../utils/conversionArrow'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import EditConversionModalComponent from './EditConversionModalComponent'; interface ConversionViewComponentProps { @@ -25,6 +25,7 @@ interface ConversionViewComponentProps { * @returns Single conversion element */ export default function ConversionViewComponent(props: ConversionViewComponentProps) { + const translate = useTranslate(); // Don't check if admin since only an admin is allow to route to this page. // Edit Modal Show diff --git a/src/client/app/components/conversion/CreateConversionModalComponent.tsx b/src/client/app/components/conversion/CreateConversionModalComponent.tsx index 6c29db3da..cb4ba8bd1 100644 --- a/src/client/app/components/conversion/CreateConversionModalComponent.tsx +++ b/src/client/app/components/conversion/CreateConversionModalComponent.tsx @@ -15,7 +15,7 @@ import '../../styles/modal.css'; import { tooltipBaseStyle } from '../../styles/modalStyle'; import { TrueFalseType } from '../../types/items'; import { showErrorNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import TooltipMarkerComponent from '../TooltipMarkerComponent'; /** @@ -23,6 +23,7 @@ import TooltipMarkerComponent from '../TooltipMarkerComponent'; * @returns Conversion create element */ export default function CreateConversionModalComponent() { + const translate = useTranslate(); const [addConversionMutation] = conversionsApi.useAddConversionMutation(); // Want units in sorted order by identifier regardless of case. diff --git a/src/client/app/components/conversion/EditConversionModalComponent.tsx b/src/client/app/components/conversion/EditConversionModalComponent.tsx index 52973c2cb..156f52d74 100644 --- a/src/client/app/components/conversion/EditConversionModalComponent.tsx +++ b/src/client/app/components/conversion/EditConversionModalComponent.tsx @@ -14,7 +14,7 @@ import '../../styles/modal.css'; import { tooltipBaseStyle } from '../../styles/modalStyle'; import { TrueFalseType } from '../../types/items'; import { ConversionData } from '../../types/redux/conversions'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import ConfirmActionModalComponent from '../ConfirmActionModalComponent'; import TooltipMarkerComponent from '../TooltipMarkerComponent'; @@ -34,6 +34,7 @@ interface EditConversionModalComponentProps { * @returns Conversion edit element */ export default function EditConversionModalComponent(props: EditConversionModalComponentProps) { + const translate = useTranslate(); const [editConversion] = conversionsApi.useEditConversionMutation(); const [deleteConversion] = conversionsApi.useDeleteConversionMutation(); const unitDataById = useAppSelector(selectUnitDataById); diff --git a/src/client/app/components/csv/MetersCSVUploadComponent.tsx b/src/client/app/components/csv/MetersCSVUploadComponent.tsx index d7414bab1..e7a6b4dbf 100644 --- a/src/client/app/components/csv/MetersCSVUploadComponent.tsx +++ b/src/client/app/components/csv/MetersCSVUploadComponent.tsx @@ -8,7 +8,7 @@ import { MetersCSVUploadPreferences } from '../../types/csvUploadForm'; import { submitMeters } from '../../utils/api/UploadCSVApi'; import { MetersCSVUploadDefaults } from '../../utils/csvUploadDefaults'; import { showErrorNotification, showSuccessNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import FormFileUploaderComponent from '../FormFileUploaderComponent'; import TooltipHelpComponent from '../TooltipHelpComponent'; import TooltipMarkerComponent from '../TooltipMarkerComponent'; @@ -22,6 +22,7 @@ import { selectVisibleMeterAndGroupData } from '../../redux/selectors/adminSelec * @returns CSV Meters page element */ export default function MetersCSVUploadComponent() { + const translate = useTranslate(); const [meterData, setMeterData] = React.useState(MetersCSVUploadDefaults); const [selectedFile, setSelectedFile] = React.useState(null); const [isValidFileType, setIsValidFileType] = React.useState(false); diff --git a/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx b/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx index a1f34fc1a..57bf137bc 100644 --- a/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx +++ b/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx @@ -16,7 +16,7 @@ import { MeterData, MeterTimeSortType } from '../../types/redux/meters'; import { submitReadings } from '../../utils/api/UploadCSVApi'; import { ReadingsCSVUploadDefaults } from '../../utils/csvUploadDefaults'; import { showErrorNotification, showSuccessNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import FormFileUploaderComponent from '../FormFileUploaderComponent'; import TooltipHelpComponent from '../TooltipHelpComponent'; import TooltipMarkerComponent from '../TooltipMarkerComponent'; @@ -27,7 +27,7 @@ import CreateMeterModalComponent from '../meters/CreateMeterModalComponent'; * @returns CSV Readings page element */ export default function ReadingsCSVUploadComponent() { - + const translate = useTranslate(); const dispatch = useAppDispatch(); // Check for admin status const isAdmin = useAppSelector(selectIsAdmin); diff --git a/src/client/app/components/groups/CreateGroupModalComponent.tsx b/src/client/app/components/groups/CreateGroupModalComponent.tsx index 21be8a6a7..fada30578 100644 --- a/src/client/app/components/groups/CreateGroupModalComponent.tsx +++ b/src/client/app/components/groups/CreateGroupModalComponent.tsx @@ -29,7 +29,7 @@ import { import { AreaUnitType, getAreaUnitConversion } from '../../utils/getAreaUnitConversion'; import { getGPSString } from '../../utils/input'; import { showErrorNotification, showWarnNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import ListDisplayComponent from '../ListDisplayComponent'; import MultiSelectComponent from '../MultiSelectComponent'; import TooltipHelpComponent from '../TooltipHelpComponent'; @@ -40,6 +40,7 @@ import TooltipMarkerComponent from '../TooltipMarkerComponent'; * @returns Group create element */ export default function CreateGroupModalComponent() { + const translate = useTranslate(); const [createGroup] = groupsApi.useCreateGroupMutation(); // Meters state diff --git a/src/client/app/components/groups/EditGroupModalComponent.tsx b/src/client/app/components/groups/EditGroupModalComponent.tsx index d72d0b42e..ba72b81e7 100644 --- a/src/client/app/components/groups/EditGroupModalComponent.tsx +++ b/src/client/app/components/groups/EditGroupModalComponent.tsx @@ -35,7 +35,7 @@ import { import { AreaUnitType, getAreaUnitConversion } from '../../utils/getAreaUnitConversion'; import { getGPSString, nullToEmptyString } from '../../utils/input'; import { showErrorNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import ConfirmActionModalComponent from '../ConfirmActionModalComponent'; import ListDisplayComponent from '../ListDisplayComponent'; import MultiSelectComponent from '../MultiSelectComponent'; @@ -57,6 +57,7 @@ interface EditGroupModalComponentProps { * @returns Group edit element */ export default function EditGroupModalComponent(props: EditGroupModalComponentProps) { + const translate = useTranslate(); const [submitGroupEdits] = groupsApi.useEditGroupMutation(); const [deleteGroup] = groupsApi.useDeleteGroupMutation(); // Meter state diff --git a/src/client/app/components/groups/GroupViewComponent.tsx b/src/client/app/components/groups/GroupViewComponent.tsx index 273459da2..8b30ae65d 100644 --- a/src/client/app/components/groups/GroupViewComponent.tsx +++ b/src/client/app/components/groups/GroupViewComponent.tsx @@ -13,7 +13,7 @@ import { useAppSelector } from '../../redux/reduxHooks'; import { selectIsAdmin } from '../../redux/slices/currentUserSlice'; import '../../styles/card-page.css'; import { noUnitTranslated } from '../../utils/input'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import EditGroupModalComponent from './EditGroupModalComponent'; interface GroupViewComponentProps { @@ -26,6 +26,7 @@ interface GroupViewComponentProps { * @returns Group info card element */ export default function GroupViewComponent(props: GroupViewComponentProps) { + const translate = useTranslate(); // Don't check if admin since only an admin is allowed to route to this page. // Edit Modal Show diff --git a/src/client/app/components/meters/CreateMeterModalComponent.tsx b/src/client/app/components/meters/CreateMeterModalComponent.tsx index 3a53cb3e4..1c0ba7702 100644 --- a/src/client/app/components/meters/CreateMeterModalComponent.tsx +++ b/src/client/app/components/meters/CreateMeterModalComponent.tsx @@ -25,7 +25,7 @@ import { MeterData, MeterTimeSortType, MeterType } from '../../types/redux/meter import { GPSPoint, isValidGPSInput } from '../../utils/calibration'; import { AreaUnitType } from '../../utils/getAreaUnitConversion'; import { showErrorNotification, showSuccessNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import TimeZoneSelect from '../TimeZoneSelect'; import TooltipHelpComponent from '../TooltipHelpComponent'; import TooltipMarkerComponent from '../TooltipMarkerComponent'; @@ -40,6 +40,7 @@ interface CreateMeterModalProps { * @returns Meter create element */ export default function CreateMeterModalComponent(props: CreateMeterModalProps): React.JSX.Element { + const translate = useTranslate(); // Tracks whether a unit/ default unit has been selected. // RTKQ Mutation to submit add meter const [submitAddMeter] = metersApi.endpoints.addMeter.useMutation(); diff --git a/src/client/app/components/meters/EditMeterModalComponent.tsx b/src/client/app/components/meters/EditMeterModalComponent.tsx index 6d1db44e1..49d3bed21 100644 --- a/src/client/app/components/meters/EditMeterModalComponent.tsx +++ b/src/client/app/components/meters/EditMeterModalComponent.tsx @@ -26,7 +26,7 @@ import { GPSPoint, isValidGPSInput } from '../../utils/calibration'; import { AreaUnitType } from '../../utils/getAreaUnitConversion'; import { getGPSString, nullToEmptyString } from '../../utils/input'; import { showErrorNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import TimeZoneSelect from '../TimeZoneSelect'; import TooltipHelpComponent from '../TooltipHelpComponent'; import TooltipMarkerComponent from '../TooltipMarkerComponent'; @@ -43,6 +43,7 @@ interface EditMeterModalComponentProps { * @returns Meter edit element */ export default function EditMeterModalComponent(props: EditMeterModalComponentProps) { + const translate = useTranslate(); const [editMeter] = metersApi.useEditMeterMutation(); // since this selector is shared amongst many other modals, we must use a selector factory in order // to have a single selector per modal instance. Memo ensures that this is a stable reference diff --git a/src/client/app/components/meters/MeterViewComponent.tsx b/src/client/app/components/meters/MeterViewComponent.tsx index a40c427fb..f3117e342 100644 --- a/src/client/app/components/meters/MeterViewComponent.tsx +++ b/src/client/app/components/meters/MeterViewComponent.tsx @@ -10,7 +10,7 @@ import { MeterData } from 'types/redux/meters'; import { useAppSelector } from '../../redux/reduxHooks'; import { selectGraphicName, selectUnitName } from '../../redux/selectors/adminSelectors'; import '../../styles/card-page.css'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; import EditMeterModalComponent from './EditMeterModalComponent'; import { selectIsAdmin } from '../../redux/slices/currentUserSlice'; @@ -24,6 +24,7 @@ interface MeterViewComponentProps { * @returns Meter info card element */ export default function MeterViewComponent(props: MeterViewComponentProps) { + const translate = useTranslate(); // Edit Modal Show const [showEditModal, setShowEditModal] = useState(false); // Check for admin status diff --git a/src/client/app/components/router/ErrorComponent.tsx b/src/client/app/components/router/ErrorComponent.tsx index bc58cbcee..58098df9e 100644 --- a/src/client/app/components/router/ErrorComponent.tsx +++ b/src/client/app/components/router/ErrorComponent.tsx @@ -6,12 +6,13 @@ import * as React from 'react'; import { useNavigate } from 'react-router-dom'; import { Button } from 'reactstrap'; import AppLayout from '../../components/AppLayout'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; /** * @returns A error page that then returns to main dashboard page. */ export default function ErrorComponent() { + const translate = useTranslate(); const nav = useNavigate(); const refreshPage = () => { nav('/'); diff --git a/src/client/app/components/router/InitializingComponent.tsx b/src/client/app/components/router/InitializingComponent.tsx index bd2346de5..25e449da9 100644 --- a/src/client/app/components/router/InitializingComponent.tsx +++ b/src/client/app/components/router/InitializingComponent.tsx @@ -4,12 +4,13 @@ import * as React from 'react'; import SpinnerComponent from '../SpinnerComponent'; -import translate from '../../utils/translate'; +import { useTranslate } from '../../redux/componentHooks'; /** * @returns A simple loading spinner used to indicate that the startup init sequence is in progress */ export default function InitializingComponent() { + const translate = useTranslate(); return (
{ // ensure a fetch is not currently happening if (!getState().conversions.isFetching) { diff --git a/src/client/app/redux/actions/map.ts b/src/client/app/redux/actions/map.ts index 8fb9d33aa..eddeb042c 100644 --- a/src/client/app/redux/actions/map.ts +++ b/src/client/app/redux/actions/map.ts @@ -16,7 +16,7 @@ import { import {State} from '../../types/redux/state'; import {mapsApi} from '../../utils/api'; import {showErrorNotification, showSuccessNotification} from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../componentHooks'; import * as moment from 'moment'; import {browserHistory} from '../../utils/history'; import {logToServer} from './logs'; @@ -232,6 +232,7 @@ export function submitCalibratingMap(): Thunk { * submit a new map to database at the end of a calibration session */ export function submitNewMap(): Thunk { + const translate = useTranslate(); return async (dispatch: Dispatch, getState: GetState) => { const mapID = getState().maps.calibratingMap; const map = getState().maps.editedMaps[mapID]; @@ -266,6 +267,7 @@ export function submitNewMap(): Thunk { * @param mapID the edited map being updated at database */ export function submitEditedMap(mapID: number): Thunk { + const translate = useTranslate(); return async (dispatch: Dispatch, getState: GetState) => { const map = getState().maps.editedMaps[mapID]; dispatch(submitMapEdits(mapID)); @@ -307,6 +309,7 @@ export function submitEditedMap(mapID: number): Thunk { * @param mapID map to be removed */ export function removeMap(mapID: number): Thunk { + const translate = useTranslate(); return async (dispatch: Dispatch) => { try { await mapsApi.delete(mapID); diff --git a/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts b/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts index 2a9b304a0..a14482140 100644 --- a/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts +++ b/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts @@ -4,11 +4,12 @@ import { isAsyncThunkAction, isRejected } from '@reduxjs/toolkit'; import { showErrorNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../componentHooks'; import { AppListener } from '../listenerMiddleware'; import { authApi } from '../api/authApi'; export const unauthorizedRequestListener = (startListening: AppListener) => { + const translate = useTranslate(); startListening({ predicate: action => { // Listens for rejected async thunks. if no payload then its an RTK internal call that needs to also be filtered. diff --git a/src/client/app/redux/selectors/adminSelectors.ts b/src/client/app/redux/selectors/adminSelectors.ts index 6f057c5d7..ddc2ceeeb 100644 --- a/src/client/app/redux/selectors/adminSelectors.ts +++ b/src/client/app/redux/selectors/adminSelectors.ts @@ -14,7 +14,7 @@ import { UnitData, UnitType } from '../../types/redux/units'; import { unitsCompatibleWithUnit } from '../../utils/determineCompatibleUnits'; import { AreaUnitType } from '../../utils/getAreaUnitConversion'; import { noUnitTranslated, potentialGraphicUnits } from '../../utils/input'; -import translate from '../../utils/translate'; +import { useTranslate } from '../componentHooks'; import { selectAllUnits, selectUnitDataById } from '../api/unitsApi'; import { selectVisibleMetersAndGroups } from './authVisibilitySelectors'; import { createAppSelector } from './selectors'; @@ -217,7 +217,7 @@ export const selectIsValidConversion = createAppSelector( Cannot mix unit represent TODO Some of these can go away when we make the menus dynamic. */ - + const translate = useTranslate(); // The destination cannot be a meter unit. if (destinationId !== -999 && unitDataById[destinationId].typeOfUnit === UnitType.meter) { return [false, translate('conversion.create.destination.meter')]; diff --git a/src/client/app/redux/selectors/lineChartSelectors.ts b/src/client/app/redux/selectors/lineChartSelectors.ts index d4ca92247..bdf5e1e6e 100644 --- a/src/client/app/redux/selectors/lineChartSelectors.ts +++ b/src/client/app/redux/selectors/lineChartSelectors.ts @@ -6,7 +6,7 @@ import * as moment from 'moment'; import { selectShowMinMax } from '../../redux/slices/graphSlice'; import { DataType } from '../../types/Datasources'; import getGraphColor from '../../utils/getGraphColor'; -import translate from '../../utils/translate'; +import { useTranslate } from '../componentHooks'; import { createAppSelector } from './selectors'; import { selectScalingFromEntity, selectNameFromEntity } from './entitySelectors'; import { selectPlotlyMeterDeps, selectPlotlyGroupDeps, selectFromLineReadingsResult } from './plotlyDataSelectors'; @@ -57,6 +57,7 @@ export const selectPlotlyMeterData = selectFromLineReadingsResult( yData.push(readingValue); // All hover have the date, meter name and value. const hoverStart = ` ${timeReading.format('ddd, ll LTS')}
${label}: ${readingValue.toPrecision(6)} ${lineUnitLabel}`; + const translate = useTranslate(); if (showMinMax && reading.max != null) { // We want to show min/max. Note if the data is raw for this meter then all the min/max values are null. // In this case we still push the min/max but plotly will not show them. This is a little extra work diff --git a/src/client/app/redux/thunks/exportThunk.ts b/src/client/app/redux/thunks/exportThunk.ts index 06eb6cc75..9cfa8023f 100644 --- a/src/client/app/redux/thunks/exportThunk.ts +++ b/src/client/app/redux/thunks/exportThunk.ts @@ -20,7 +20,7 @@ import { ConversionData } from '../../types/redux/conversions'; import { ChartTypes, MeterOrGroup } from '../../types/redux/graph'; import graphExport, { downloadRawCSV } from '../../utils/exportData'; import { showErrorNotification } from '../../utils/notifications'; -import translate from '../../utils/translate'; +import { useTranslate } from '../componentHooks'; import { createAppThunk } from './appThunk'; import { selectAnythingFetching } from '../../redux/selectors/apiSelectors'; import { RootState } from '../../store'; @@ -115,6 +115,7 @@ export const exportGraphReadingsThunk = createAppThunk( export const exportRawReadings = createAppThunk( 'graph/ExportRaw', async (_arg, api) => { + const translate = useTranslate(); const state = api.getState(); if (!selectCanExport(state)) { return api.rejectWithValue('Data Fetch In Progress, Or No data'); diff --git a/src/client/app/utils/calculateCompare.ts b/src/client/app/utils/calculateCompare.ts index 499c5bac1..ff9c1b3bb 100644 --- a/src/client/app/utils/calculateCompare.ts +++ b/src/client/app/utils/calculateCompare.ts @@ -4,7 +4,7 @@ import { TimeInterval } from '../../../common/TimeInterval'; import * as moment from 'moment'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; /** * 'Day', 'Week' or 'FourWeeks' @@ -159,6 +159,7 @@ export interface ComparePeriodLabels { * @returns human-readable names for the compare period as {{prev: string, current: string}} */ export function getComparePeriodLabels(comparePeriod: ComparePeriod): ComparePeriodLabels { + const translate = useTranslate(); switch (comparePeriod) { case ComparePeriod.Day: return { prev: translate('yesterday'), current: translate('today') }; @@ -180,6 +181,7 @@ export function getComparePeriodLabels(comparePeriod: ComparePeriod): ComparePer * @returns The label summary */ export function getCompareChangeSummary(change: number, name: string, labels: ComparePeriodLabels): string { + const translate = useTranslate(); if (isNaN(change)) { return `${name} ${translate('has.no.data')}`; } diff --git a/src/client/app/utils/calibration.ts b/src/client/app/utils/calibration.ts index 7ec057a4b..2e197b2dc 100644 --- a/src/client/app/utils/calibration.ts +++ b/src/client/app/utils/calibration.ts @@ -6,7 +6,7 @@ import { showErrorNotification } from './notifications'; import { logToServer } from '../redux/actions/logs'; import { DataType } from '../types/Datasources'; import { MapMetadata } from '../types/redux/map'; -import translate from './translate'; +import { useTranslate } from '../redux/componentHooks'; /** * Defines a Cartesian Point with x & y @@ -107,6 +107,7 @@ export function itemDisplayableOnMap(size: Dimensions, point: CartesianPoint): b * @returns true if string is GPS and false otherwise. */ export function isValidGPSInput(input: string): boolean { + const translate = useTranslate(); if (input.indexOf(',') === -1) { // if there is no comma // TODO It would be nice to tell user that comma is missing but need to check all uses to be sure don't get ''. return false; diff --git a/src/client/app/utils/graphics.ts b/src/client/app/utils/graphics.ts index cb2e64d34..08f03c897 100644 --- a/src/client/app/utils/graphics.ts +++ b/src/client/app/utils/graphics.ts @@ -4,7 +4,7 @@ import { LineGraphRate } from 'types/redux/graph'; import { UnitData, UnitRepresentType } from '../types/redux/units'; -import translate from '../utils/translate'; +import { useTranslate } from '../redux/componentHooks'; import { AreaUnitType } from './getAreaUnitConversion'; // Has functions for use with graphics @@ -19,7 +19,7 @@ import { AreaUnitType } from './getAreaUnitConversion'; */ export function lineUnitLabel(selectUnitState: UnitData, currentSelectedRate: LineGraphRate, areaNormalization: boolean, selectedAreaUnit: AreaUnitType): { unitLabel: string, needsRateScaling: boolean } { - + const translate = useTranslate(); let unitLabel: string = ''; let needsRateScaling = false; // Quantity and flow units have different unit labels. @@ -60,6 +60,7 @@ export function lineUnitLabel(selectUnitState: UnitData, currentSelectedRate: Li * @returns y-axis label */ export function barUnitLabel(selectUnitState: UnitData, areaNormalization: boolean, selectedAreaUnit: AreaUnitType): string { + const translate = useTranslate(); let unitLabel: string = ''; // Quantity and flow units have different unit labels. // Look up the type of unit if it is for quantity/flow (should not be raw) and decide what to do. diff --git a/src/client/app/utils/input.ts b/src/client/app/utils/input.ts index d6c67fae4..da34ab302 100644 --- a/src/client/app/utils/input.ts +++ b/src/client/app/utils/input.ts @@ -4,7 +4,7 @@ import { GPSPoint } from './calibration'; import { UnitData, DisplayableType, UnitRepresentType, UnitType, UnitDataById } from '../types/redux/units'; -import translate from './translate'; +import { useTranslate } from '../redux/componentHooks'; import { sortBy } from 'lodash'; /** @@ -87,6 +87,7 @@ export const NoUnit: UnitData = { * @returns a unit to represent no unit with translated identifier */ export function noUnitTranslated(): UnitData { + const translate = useTranslate(); // Untranslated no unit. const unit = NoUnit; // Make the identifier be translated. From 6e12e8f88d1040f6f12be01f76afe541ef8a078c Mon Sep 17 00:00:00 2001 From: Joijanae Laws Date: Fri, 4 Oct 2024 19:01:29 -0500 Subject: [PATCH 2/5] Standardize translation method --- src/client/app/components/AreaUnitSelectComponent.tsx | 2 +- src/client/app/components/BarChartComponent.tsx | 2 +- src/client/app/components/BarControlsComponent.tsx | 2 +- src/client/app/components/ChartLinkComponent.tsx | 2 +- src/client/app/components/ChartSelectComponent.tsx | 2 +- src/client/app/components/CompareControlsComponent.tsx | 2 +- src/client/app/components/ConfirmActionModalComponent.tsx | 2 +- src/client/app/components/DateRangeComponent.tsx | 2 +- src/client/app/components/ErrorBarComponent.tsx | 2 +- src/client/app/components/FormFileUploaderComponent.tsx | 2 +- src/client/app/components/GraphicRateMenuComponent.tsx | 2 +- src/client/app/components/HeaderButtonsComponent.tsx | 2 +- src/client/app/components/LineChartComponent.tsx | 2 +- src/client/app/components/LoginComponent.tsx | 2 +- src/client/app/components/MapChartComponent.tsx | 2 +- src/client/app/components/MapControlsComponent.tsx | 2 +- src/client/app/components/MeterAndGroupSelectComponent.tsx | 2 +- src/client/app/components/MoreOptionsComponent.tsx | 2 +- src/client/app/components/RadarChartComponent.tsx | 2 +- src/client/app/components/ReadingsPerDaySelectComponent.tsx | 2 +- src/client/app/components/ThreeDComponent.tsx | 6 +++--- src/client/app/components/ThreeDPillComponent.tsx | 2 +- src/client/app/components/TimeZoneSelect.tsx | 2 +- src/client/app/components/TooltipHelpComponent.tsx | 2 +- src/client/app/components/UnitSelectComponent.tsx | 2 +- src/client/app/components/UnsavedWarningComponent.tsx | 2 +- src/client/app/components/admin/PreferencesComponent.tsx | 2 +- .../app/components/admin/users/CreateUserModalComponent.tsx | 2 +- .../app/components/admin/users/EditUserModalComponent.tsx | 2 +- src/client/app/components/admin/users/UserViewComponent.tsx | 2 +- .../app/components/admin/users/UsersDetailComponent.tsx | 2 +- .../app/components/conversion/ConversionViewComponent.tsx | 2 +- .../conversion/CreateConversionModalComponent.tsx | 2 +- .../components/conversion/EditConversionModalComponent.tsx | 2 +- src/client/app/components/csv/MetersCSVUploadComponent.tsx | 2 +- .../app/components/csv/ReadingsCSVUploadComponent.tsx | 2 +- .../app/components/groups/CreateGroupModalComponent.tsx | 2 +- .../app/components/groups/EditGroupModalComponent.tsx | 2 +- src/client/app/components/groups/GroupViewComponent.tsx | 2 +- .../app/components/meters/CreateMeterModalComponent.tsx | 2 +- .../app/components/meters/EditMeterModalComponent.tsx | 2 +- src/client/app/components/meters/MeterViewComponent.tsx | 2 +- src/client/app/components/router/ErrorComponent.tsx | 2 +- src/client/app/components/unit/UnitViewComponent.tsx | 2 +- src/client/app/containers/CompareChartContainer.ts | 2 +- src/client/app/containers/MapChartContainer.ts | 2 +- .../containers/maps/MapCalibrationInfoDisplayContainer.ts | 2 +- src/client/app/redux/actions/conversions.ts | 4 +++- src/client/app/redux/actions/map.ts | 6 +++--- .../app/redux/middleware/unauthorizedAccesMiddleware.ts | 2 +- src/client/app/redux/thunks/exportThunk.ts | 2 +- src/client/app/utils/calibration.ts | 2 +- src/client/app/utils/graphics.ts | 2 +- src/client/app/utils/input.ts | 2 +- 54 files changed, 60 insertions(+), 58 deletions(-) diff --git a/src/client/app/components/AreaUnitSelectComponent.tsx b/src/client/app/components/AreaUnitSelectComponent.tsx index 739e6fb26..58ad7266b 100644 --- a/src/client/app/components/AreaUnitSelectComponent.tsx +++ b/src/client/app/components/AreaUnitSelectComponent.tsx @@ -20,12 +20,12 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; */ export default function AreaUnitSelectComponent() { const dispatch = useAppDispatch(); - const translate = useTranslate(); const graphState = useAppSelector(selectGraphState); const unitDataById = useAppSelector(selectUnitDataById); // Array of select options created from the area unit enum const unitOptions: StringSelectOption[] = []; + const translate = useTranslate(); Object.keys(AreaUnitType).forEach(unitKey => { // don't allow normalization by no unit diff --git a/src/client/app/components/BarChartComponent.tsx b/src/client/app/components/BarChartComponent.tsx index e3a7ed65c..2d7e3fad1 100644 --- a/src/client/app/components/BarChartComponent.tsx +++ b/src/client/app/components/BarChartComponent.tsx @@ -27,7 +27,6 @@ import SpinnerComponent from './SpinnerComponent'; * @returns Plotly BarChart */ export default function BarChartComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const { barMeterDeps, barGroupDeps } = useAppSelector(selectPlotlyBarDeps); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectBarChartQueryArgs); @@ -56,6 +55,7 @@ export default function BarChartComponent() { // useQueryHooks for data fetching const datasets: Partial[] = meterReadings.concat(groupData); + const translate = useTranslate(); if (meterIsFetching || groupIsFetching) { return ; diff --git a/src/client/app/components/BarControlsComponent.tsx b/src/client/app/components/BarControlsComponent.tsx index ead20b67c..8b89408df 100644 --- a/src/client/app/components/BarControlsComponent.tsx +++ b/src/client/app/components/BarControlsComponent.tsx @@ -15,7 +15,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns controls for the Options Ui page. */ export default function BarControlsComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); // The min/max days allowed for user selection @@ -90,6 +89,7 @@ export default function BarControlsComponent() { dispatch(graphSlice.actions.updateBarDuration(moment.duration(value, 'days'))); } }; + const translate = useTranslate(); return (
diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 6de7aabae..547abea7d 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -18,7 +18,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns chartLinkComponent */ export default function ChartLinkComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const [linkTextVisible, setLinkTextVisible] = React.useState(false); const linkText = useAppSelector(selectChartLink); @@ -26,6 +25,7 @@ export default function ChartLinkComponent() { const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); const ref = React.useRef(null); + const translate = useTranslate(); const handleButtonClick = () => { // First attempt to write directly to user's clipboard. navigator.clipboard.writeText(linkText) diff --git a/src/client/app/components/ChartSelectComponent.tsx b/src/client/app/components/ChartSelectComponent.tsx index 494bae623..739226a2a 100644 --- a/src/client/app/components/ChartSelectComponent.tsx +++ b/src/client/app/components/ChartSelectComponent.tsx @@ -21,7 +21,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Chart select element */ export default function ChartSelectComponent() { - const translate = useTranslate(); const currentChartToRender = useAppSelector(selectChartToRender); const dispatch = useAppDispatch(); const [expand, setExpand] = useState(false); @@ -29,6 +28,7 @@ export default function ChartSelectComponent() { const sortedMaps = sortBy(values(mapsById).map(map => ( { value: map.id, label: map.name, isDisabled: !(map.origin && map.opposite) } as SelectOption )), 'label'); + const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/CompareControlsComponent.tsx b/src/client/app/components/CompareControlsComponent.tsx index 5b9cd3447..76d6c8c83 100644 --- a/src/client/app/components/CompareControlsComponent.tsx +++ b/src/client/app/components/CompareControlsComponent.tsx @@ -15,7 +15,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns controls for the compare page */ export default function CompareControlsComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const comparePeriod = useAppSelector(selectComparePeriod); const compareSortingOrder = useAppSelector(selectSortingOrder); @@ -26,6 +25,7 @@ export default function CompareControlsComponent() { const handleSortingButton = (sortingOrder: SortingOrder) => { dispatch(graphSlice.actions.changeCompareSortingOrder(sortingOrder)); }; + const translate = useTranslate(); return (
diff --git a/src/client/app/components/ConfirmActionModalComponent.tsx b/src/client/app/components/ConfirmActionModalComponent.tsx index 9f15d58b7..b6aa27e74 100644 --- a/src/client/app/components/ConfirmActionModalComponent.tsx +++ b/src/client/app/components/ConfirmActionModalComponent.tsx @@ -41,10 +41,10 @@ interface ConfirmActionModalComponentProps { * @returns A modal component that executes the actionFunction on confirmation and handleClose on rejection. */ export default function ConfirmActionModalComponent(props: ConfirmActionModalComponentProps) { - const translate = useTranslate(); const handleClose = () => { props.handleClose(); }; + const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/DateRangeComponent.tsx b/src/client/app/components/DateRangeComponent.tsx index 033b311e3..8cc374d33 100644 --- a/src/client/app/components/DateRangeComponent.tsx +++ b/src/client/app/components/DateRangeComponent.tsx @@ -22,7 +22,6 @@ import { ChartTypes } from '../types/redux/graph'; * @returns Date Range Calendar Picker */ export default function DateRangeComponent() { - const translate = useTranslate(); const dispatch: Dispatch = useAppDispatch(); const queryTimeInterval = useAppSelector(selectQueryTimeInterval); const locale = useAppSelector(selectSelectedLanguage); @@ -33,6 +32,7 @@ export default function DateRangeComponent() { dispatch(updateTimeInterval(dateRangeToTimeInterval(value))); dispatch(changeSliderRange(dateRangeToTimeInterval(value))); }; + const translate = useTranslate(); return ( diff --git a/src/client/app/components/ErrorBarComponent.tsx b/src/client/app/components/ErrorBarComponent.tsx index 957adb04b..9fe1f8282 100644 --- a/src/client/app/components/ErrorBarComponent.tsx +++ b/src/client/app/components/ErrorBarComponent.tsx @@ -13,9 +13,9 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Error Bar checkbox with tooltip and label */ export default function ErrorBarComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const showMinMax = useAppSelector(selectShowMinMax); + const translate = useTranslate(); return (
diff --git a/src/client/app/components/FormFileUploaderComponent.tsx b/src/client/app/components/FormFileUploaderComponent.tsx index 714001f63..2d90906cf 100644 --- a/src/client/app/components/FormFileUploaderComponent.tsx +++ b/src/client/app/components/FormFileUploaderComponent.tsx @@ -17,11 +17,11 @@ interface FileUploader { * @returns File uploader element */ export default function FileUploaderComponent(props: FileUploader) { - const translate = useTranslate(); const handleFileChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0] || null; props.onFileChange(file); }; + const translate = useTranslate(); return ( diff --git a/src/client/app/components/GraphicRateMenuComponent.tsx b/src/client/app/components/GraphicRateMenuComponent.tsx index febe41352..9d8717964 100644 --- a/src/client/app/components/GraphicRateMenuComponent.tsx +++ b/src/client/app/components/GraphicRateMenuComponent.tsx @@ -19,7 +19,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Rate selection element */ export default function GraphicRateMenuComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); // Graph state @@ -49,6 +48,7 @@ export default function GraphicRateMenuComponent() { } // Array of select options created from the rates const rateOptions: SelectOption[] = []; + const translate = useTranslate(); //Loop over our rates object to create the selects for the dropdown Object.entries(LineGraphRates).forEach(([rateKey, rateValue]) => { diff --git a/src/client/app/components/HeaderButtonsComponent.tsx b/src/client/app/components/HeaderButtonsComponent.tsx index 58f41e53e..fc9a67b47 100644 --- a/src/client/app/components/HeaderButtonsComponent.tsx +++ b/src/client/app/components/HeaderButtonsComponent.tsx @@ -25,7 +25,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Header buttons element */ export default function HeaderButtonsComponent() { - const translate = useTranslate(); const [logout] = authApi.useLogoutMutation(); const dispatch = useAppDispatch(); // Get the current page so know which one should not be shown in menu. @@ -75,6 +74,7 @@ export default function HeaderButtonsComponent() { // TODO Re-implement AFTER RTK Migration // hard-coded for the time being. Rework w/admin pages const unsavedChangesState = false; + const translate = useTranslate(); // Must update in case the version was not set when the page was loaded. diff --git a/src/client/app/components/LineChartComponent.tsx b/src/client/app/components/LineChartComponent.tsx index 95c0d294e..adf658d3b 100644 --- a/src/client/app/components/LineChartComponent.tsx +++ b/src/client/app/components/LineChartComponent.tsx @@ -24,7 +24,6 @@ import SpinnerComponent from './SpinnerComponent'; * @returns plotlyLine graphic */ export default function LineChartComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); // get current data fetching arguments const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectLineChartQueryArgs); @@ -67,6 +66,7 @@ export default function LineChartComponent() { // Check if there is at least one valid graph const enoughData = data.find(data => data.x!.length > 1); + const translate = useTranslate(); // Customize the layout of the plot // See https://community.plotly.com/t/replacing-an-empty-graph-with-a-message/31497 for showing text not plot. if (data.length === 0) { diff --git a/src/client/app/components/LoginComponent.tsx b/src/client/app/components/LoginComponent.tsx index d182fd13d..399199312 100644 --- a/src/client/app/components/LoginComponent.tsx +++ b/src/client/app/components/LoginComponent.tsx @@ -16,7 +16,6 @@ import { useTranslate } from '../redux/componentHooks'; * @returns The login page for users or admins. */ export default function LoginComponent() { - const translate = useTranslate(); // Local State const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -29,6 +28,7 @@ export default function LoginComponent() { // The naming of the returned objects is arbitrary // Equivalent Auto-Derived Method const [login] = authApi.endpoints.login.useMutation(); // authApi.useLoginMutation() + const translate = useTranslate(); const handleSubmit = async (event: React.MouseEvent) => { event.preventDefault(); diff --git a/src/client/app/components/MapChartComponent.tsx b/src/client/app/components/MapChartComponent.tsx index baf02d3b4..a0e64a35d 100644 --- a/src/client/app/components/MapChartComponent.tsx +++ b/src/client/app/components/MapChartComponent.tsx @@ -39,7 +39,6 @@ import SpinnerComponent from './SpinnerComponent'; * @returns map component */ export default function MapChartComponent() { - const translate = useTranslate(); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectMapChartQueryArgs); const { data: meterReadings, isLoading: meterIsFetching } = readingsApi.useBarQuery(meterArgs, { skip: meterShouldSkip }); const { data: groupData, isLoading: groupIsFetching } = readingsApi.useBarQuery(groupArgs, { skip: groupShouldSkip }); @@ -71,6 +70,7 @@ export default function MapChartComponent() { const data = []; // Holds the image to use. let image; + const translate = useTranslate(); if (selectedMap !== 0) { const mapID = selectedMap; if (byMapID[mapID]) { diff --git a/src/client/app/components/MapControlsComponent.tsx b/src/client/app/components/MapControlsComponent.tsx index 9a3a10ddc..73849f0d0 100644 --- a/src/client/app/components/MapControlsComponent.tsx +++ b/src/client/app/components/MapControlsComponent.tsx @@ -15,7 +15,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Map page controls */ export default function MapControlsComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const barDuration = useAppSelector(selectMapBarWidthDays); @@ -24,6 +23,7 @@ export default function MapControlsComponent() { }; const barDurationDays = barDuration.asDays(); + const translate = useTranslate(); return (
diff --git a/src/client/app/components/MeterAndGroupSelectComponent.tsx b/src/client/app/components/MeterAndGroupSelectComponent.tsx index 67f0b8015..b85001741 100644 --- a/src/client/app/components/MeterAndGroupSelectComponent.tsx +++ b/src/client/app/components/MeterAndGroupSelectComponent.tsx @@ -25,7 +25,6 @@ import { selectAnythingFetching } from '../redux/selectors/apiSelectors'; * @returns A React-Select component. */ export default function MeterAndGroupSelectComponent(props: MeterAndGroupSelectProps) { - const translate = useTranslate(); const dispatch = useAppDispatch(); const { meterGroupedOptions, groupsGroupedOptions, allSelectedMeterValues, allSelectedGroupValues } = useAppSelector(selectMeterGroupSelectData); const somethingIsFetching = useAppSelector(selectAnythingFetching); @@ -40,6 +39,7 @@ export default function MeterAndGroupSelectComponent(props: MeterAndGroupSelectP const newMetersOrGroups = newValues.map(option => option.value); dispatch(updateSelectedMetersOrGroups({ newMetersOrGroups, meta })); }; + const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/MoreOptionsComponent.tsx b/src/client/app/components/MoreOptionsComponent.tsx index bdc860ab3..be5047594 100644 --- a/src/client/app/components/MoreOptionsComponent.tsx +++ b/src/client/app/components/MoreOptionsComponent.tsx @@ -22,13 +22,13 @@ import { useTranslate } from '../redux/componentHooks'; * @returns Custom Modal depending on selected graph type */ export default function MoreOptionsComponent() { - const translate = useTranslate(); const chartToRender = useAppSelector(selectChartToRender); const [showModal, setShowModal] = useState(false); const handleShow = () => setShowModal(true); const handleClose = () => { setShowModal(false); }; + const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/RadarChartComponent.tsx b/src/client/app/components/RadarChartComponent.tsx index 3ff51879b..5c382bc17 100644 --- a/src/client/app/components/RadarChartComponent.tsx +++ b/src/client/app/components/RadarChartComponent.tsx @@ -29,7 +29,6 @@ import SpinnerComponent from './SpinnerComponent'; * @returns radar plotly component */ export default function RadarChartComponent() { - const translate = useTranslate(); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectRadarChartQueryArgs); const { data: meterReadings, isLoading: meterIsLoading } = readingsApi.useLineQuery(meterArgs, { skip: meterShouldSkip }); const { data: groupData, isLoading: groupIsLoading } = readingsApi.useLineQuery(groupArgs, { skip: groupShouldSkip }); @@ -67,6 +66,7 @@ export default function RadarChartComponent() { } // The rate will be 1 if it is per hour (since state readings are per hour) or no rate scaling so no change. const rateScaling = needsRateScaling ? currentSelectedRate.rate : 1; + const translate = useTranslate(); // Add all valid data from existing meters to the radar plot for (const meterID of selectedMeters) { diff --git a/src/client/app/components/ReadingsPerDaySelectComponent.tsx b/src/client/app/components/ReadingsPerDaySelectComponent.tsx index 40a56cbd0..c7e7511b6 100644 --- a/src/client/app/components/ReadingsPerDaySelectComponent.tsx +++ b/src/client/app/components/ReadingsPerDaySelectComponent.tsx @@ -18,7 +18,6 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns A Select menu with Readings per day options. */ export default function ReadingsPerDaySelect() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const readingInterval = useAppSelector(selectThreeDReadingInterval); const { args, shouldSkipQuery } = useAppSelector(selectThreeDQueryArgs); @@ -30,6 +29,7 @@ export default function ReadingsPerDaySelect() { ...selectReadingsPerDaySelectData(currentData ?? stableEmptyThreeDReadings, readingInterval) }) }); + const translate = useTranslate(); return (
diff --git a/src/client/app/components/ThreeDComponent.tsx b/src/client/app/components/ThreeDComponent.tsx index ba512e23d..f56970755 100644 --- a/src/client/app/components/ThreeDComponent.tsx +++ b/src/client/app/components/ThreeDComponent.tsx @@ -32,7 +32,6 @@ import Locales from '../types/locales'; * @returns 3D Plotly 3D Surface Graph */ export default function ThreeDComponent() { - const translate = useTranslate(); const { args, shouldSkipQuery } = useAppSelector(selectThreeDQueryArgs); const { data, isFetching } = readingsApi.endpoints.threeD.useQuery(args, { skip: shouldSkipQuery }); const meterDataById = useAppSelector(selectMeterDataById); @@ -47,6 +46,7 @@ export default function ThreeDComponent() { const threeDData = data; let layout = {}; let dataToRender = null; + const translate = useTranslate(); if (!meterOrGroupID) { @@ -125,6 +125,7 @@ function formatThreeDData( const currentSelectedRate = graphState.lineGraphRate; let unitLabel = ''; let needsRateScaling = false; + const translate = useTranslate(); if (graphingUnit !== -99) { const selectUnitState = unitDataById[graphState.selectedUnit]; if (selectUnitState !== undefined) { @@ -159,7 +160,6 @@ function formatThreeDData( // Calculate Hover Text, and populate xLabels/yLabels const hoverText = zDataToRender.map((day, i) => day.map((readings, j) => { - const translate = useTranslate(); const startTS = moment.utc(data.xData[j].startTimestamp); const endTS = moment.utc(data.xData[j].endTimestamp); const midpointTS = moment.utc(startTS.clone().add(endTS.clone().diff(startTS) / 2)); @@ -229,12 +229,12 @@ function setHelpLayout(helpText: string = 'Help Text Goes Here', fontSize: numbe * @returns plotly layout object. */ function setThreeDLayout(zLabelText: string = 'Resource Usage', yDataToRender: string[]) { - const translate = useTranslate(); // Convert date strings to JavaScript Date objects and then get dataRange const dateObjects = yDataToRender.map(dateStr => new Date(dateStr)); const dataMin = Math.min(...dateObjects.map(date => date.getTime())); const dataMax = Math.max(...dateObjects.map(date => date.getTime())); const dataRange = dataMax - dataMin; + const translate = useTranslate(); //Calculate nTicks for small num of days on y-axis; possibly a better way let nTicks, dTick = 'd1'; diff --git a/src/client/app/components/ThreeDPillComponent.tsx b/src/client/app/components/ThreeDPillComponent.tsx index cbc637e7a..3f8610cf7 100644 --- a/src/client/app/components/ThreeDPillComponent.tsx +++ b/src/client/app/components/ThreeDPillComponent.tsx @@ -17,7 +17,6 @@ import { useTranslate } from '../redux/componentHooks'; * @returns List of selected groups and meters as reactstrap Pills Badges */ export default function ThreeDPillComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const meterDataById = useAppSelector(selectMeterDataById); const groupDataById = useAppSelector(selectGroupDataById); @@ -82,6 +81,7 @@ export default function ThreeDPillComponent() { ); }); }; + const translate = useTranslate(); return (
diff --git a/src/client/app/components/TimeZoneSelect.tsx b/src/client/app/components/TimeZoneSelect.tsx index 10a740e54..50c3e5d9b 100644 --- a/src/client/app/components/TimeZoneSelect.tsx +++ b/src/client/app/components/TimeZoneSelect.tsx @@ -15,7 +15,6 @@ interface TimeZoneSelectProps { } const TimeZoneSelect: React.FC = ({ current, handleClick }) => { - const translate = useTranslate(); const getTimeZones = () => { const zoneNames = moment.tz.names(); @@ -25,6 +24,7 @@ const TimeZoneSelect: React.FC = ({ current, handleClick }) return { value: zoneName, label: `${zoneName} (${abbrev})` }; }); }; + const translate = useTranslate(); const resetTimeZone = [{ value: null, label: translate('timezone.no') }]; const options = [...resetTimeZone, ...getTimeZones()]; diff --git a/src/client/app/components/TooltipHelpComponent.tsx b/src/client/app/components/TooltipHelpComponent.tsx index b7decbf4d..5c08947bb 100644 --- a/src/client/app/components/TooltipHelpComponent.tsx +++ b/src/client/app/components/TooltipHelpComponent.tsx @@ -20,7 +20,6 @@ interface TooltipHelpProps { * @returns ToolTipHelpComponent */ export default function TooltipHelpComponent(props: TooltipHelpProps) { - const translate = useTranslate(); /** * @returns JSX to create the help icons with links */ @@ -73,6 +72,7 @@ export default function TooltipHelpComponent(props: TooltipHelpProps) { 'help.groups.groupview': { link: `${helpUrl}/groupViewing/` }, 'help.meters.meterview': { link: `${helpUrl}/meterViewing/` } }; + const translate = useTranslate(); return (
diff --git a/src/client/app/components/UnitSelectComponent.tsx b/src/client/app/components/UnitSelectComponent.tsx index f07e478de..a4689a10a 100644 --- a/src/client/app/components/UnitSelectComponent.tsx +++ b/src/client/app/components/UnitSelectComponent.tsx @@ -19,7 +19,6 @@ import { selectUnitDataById, unitsApi } from '../redux/api/unitsApi'; * @returns A React-Select component for UI Options Panel */ export default function UnitSelectComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const unitSelectOptions = useAppSelector(selectUnitSelectData); const selectedUnitID = useAppSelector(selectSelectedUnit); @@ -39,6 +38,7 @@ export default function UnitSelectComponent() { } const onChange = (newValue: SelectOption) => dispatch(graphSlice.actions.updateSelectedUnit(newValue?.value)); + const translate = useTranslate(); return (
diff --git a/src/client/app/components/UnsavedWarningComponent.tsx b/src/client/app/components/UnsavedWarningComponent.tsx index 313a288d9..d68254c93 100644 --- a/src/client/app/components/UnsavedWarningComponent.tsx +++ b/src/client/app/components/UnsavedWarningComponent.tsx @@ -25,9 +25,9 @@ export interface UnsavedWarningProps { * @returns Component that prompts before navigating away from current page */ export function UnsavedWarningComponent(props: UnsavedWarningProps) { - const translate = useTranslate(); const { hasUnsavedChanges, submitChanges, changes } = props; const blocker = useBlocker(hasUnsavedChanges); + const translate = useTranslate(); const handleSubmit = async () => { submitChanges(changes) .unwrap() diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index ffc2717cb..5628f5e17 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -23,7 +23,6 @@ import { defaultAdminState } from '../../redux/slices/adminSlice'; * @returns Preferences Component for Administrative use */ export default function PreferencesComponent() { - const translate = useTranslate(); const { data: adminPreferences = defaultAdminState } = preferencesApi.useGetPreferencesQuery(); const [localAdminPref, setLocalAdminPref] = React.useState(cloneDeep(adminPreferences)); const [submitPreferences] = preferencesApi.useSubmitPreferencesMutation(); @@ -42,6 +41,7 @@ export default function PreferencesComponent() { const discardChanges = () => { setLocalAdminPref(cloneDeep(adminPreferences)); }; + const translate = useTranslate(); return (
diff --git a/src/client/app/components/admin/users/CreateUserModalComponent.tsx b/src/client/app/components/admin/users/CreateUserModalComponent.tsx index 0594c73ff..2319f0b29 100644 --- a/src/client/app/components/admin/users/CreateUserModalComponent.tsx +++ b/src/client/app/components/admin/users/CreateUserModalComponent.tsx @@ -21,7 +21,6 @@ import { tooltipBaseStyle } from '../../../styles/modalStyle'; * @returns CreateUserModal component */ export default function CreateUserModal() { - const translate = useTranslate(); // create user form state and use the defaults const [userDetails, setUserDetails] = useState(userDefaults); @@ -86,6 +85,7 @@ export default function CreateUserModal() { setShowModal(false); }; // End Modal show/close + const translate = useTranslate(); const handleSubmit = async () => { const newUser: User = { username: userDetails.username, role: userDetails.role, password: userDetails.password, note: userDetails.note }; diff --git a/src/client/app/components/admin/users/EditUserModalComponent.tsx b/src/client/app/components/admin/users/EditUserModalComponent.tsx index 4568b2704..fad2a83f6 100644 --- a/src/client/app/components/admin/users/EditUserModalComponent.tsx +++ b/src/client/app/components/admin/users/EditUserModalComponent.tsx @@ -29,7 +29,6 @@ interface EditUserModalComponentProps { * @returns User edit element */ export default function EditUserModalComponent(props: EditUserModalComponentProps) { - const translate = useTranslate(); // get current logged in user const currentLoggedInUser = useAppSelector(selectCurrentUserProfile) as User; @@ -86,6 +85,7 @@ export default function EditUserModalComponent(props: EditUserModalComponentProp confirmPassword: '' })); }; + const translate = useTranslate(); /* Confirm Delete Modal */ // Separate from state comment to keep everything related to the warning confirmation modal together diff --git a/src/client/app/components/admin/users/UserViewComponent.tsx b/src/client/app/components/admin/users/UserViewComponent.tsx index 0420c3032..099d369c0 100644 --- a/src/client/app/components/admin/users/UserViewComponent.tsx +++ b/src/client/app/components/admin/users/UserViewComponent.tsx @@ -21,7 +21,6 @@ interface UserViewComponentProps { * @returns User card element */ export default function UserViewComponent(props: UserViewComponentProps) { - const translate = useTranslate(); const [showEditModal, setShowEditModal] = useState(false); const handleShow = () => { @@ -31,6 +30,7 @@ export default function UserViewComponent(props: UserViewComponentProps) { const handleClose = () => { setShowEditModal(false); }; + const translate = useTranslate(); return (
diff --git a/src/client/app/components/admin/users/UsersDetailComponent.tsx b/src/client/app/components/admin/users/UsersDetailComponent.tsx index c01c382db..83e819d00 100644 --- a/src/client/app/components/admin/users/UsersDetailComponent.tsx +++ b/src/client/app/components/admin/users/UsersDetailComponent.tsx @@ -22,8 +22,8 @@ const tooltipStyle = { * @returns User Detail element */ export default function UserDetailComponent() { - const translate = useTranslate(); const { data: users = stableEmptyUsers } = userApi.useGetUsersQuery(); + const translate = useTranslate(); return (
diff --git a/src/client/app/components/conversion/ConversionViewComponent.tsx b/src/client/app/components/conversion/ConversionViewComponent.tsx index c63642372..749c577cb 100644 --- a/src/client/app/components/conversion/ConversionViewComponent.tsx +++ b/src/client/app/components/conversion/ConversionViewComponent.tsx @@ -25,7 +25,6 @@ interface ConversionViewComponentProps { * @returns Single conversion element */ export default function ConversionViewComponent(props: ConversionViewComponentProps) { - const translate = useTranslate(); // Don't check if admin since only an admin is allow to route to this page. // Edit Modal Show @@ -45,6 +44,7 @@ export default function ConversionViewComponent(props: ConversionViewComponentPr unitDataById[props.conversion.destinationId]?.identifier); // Unlike the details component, we don't check if units are loaded since must come through that page. + const translate = useTranslate(); return (
diff --git a/src/client/app/components/conversion/CreateConversionModalComponent.tsx b/src/client/app/components/conversion/CreateConversionModalComponent.tsx index cb4ba8bd1..f383555c2 100644 --- a/src/client/app/components/conversion/CreateConversionModalComponent.tsx +++ b/src/client/app/components/conversion/CreateConversionModalComponent.tsx @@ -23,7 +23,6 @@ import TooltipMarkerComponent from '../TooltipMarkerComponent'; * @returns Conversion create element */ export default function CreateConversionModalComponent() { - const translate = useTranslate(); const [addConversionMutation] = conversionsApi.useAddConversionMutation(); // Want units in sorted order by identifier regardless of case. @@ -99,6 +98,7 @@ export default function CreateConversionModalComponent() { ...tooltipBaseStyle, tooltipCreateConversionView: 'help.admin.conversioncreate' }; + const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/conversion/EditConversionModalComponent.tsx b/src/client/app/components/conversion/EditConversionModalComponent.tsx index 156f52d74..155aa8464 100644 --- a/src/client/app/components/conversion/EditConversionModalComponent.tsx +++ b/src/client/app/components/conversion/EditConversionModalComponent.tsx @@ -34,7 +34,6 @@ interface EditConversionModalComponentProps { * @returns Conversion edit element */ export default function EditConversionModalComponent(props: EditConversionModalComponentProps) { - const translate = useTranslate(); const [editConversion] = conversionsApi.useEditConversionMutation(); const [deleteConversion] = conversionsApi.useDeleteConversionMutation(); const unitDataById = useAppSelector(selectUnitDataById); @@ -58,6 +57,7 @@ export default function EditConversionModalComponent(props: EditConversionModalC setState({ ...state, [e.target.name]: Number(e.target.value) }); }; /* End State */ + const translate = useTranslate(); /* Confirm Delete Modal */ // Separate from state comment to keep everything related to the warning confirmation modal together diff --git a/src/client/app/components/csv/MetersCSVUploadComponent.tsx b/src/client/app/components/csv/MetersCSVUploadComponent.tsx index e7a6b4dbf..eee66614e 100644 --- a/src/client/app/components/csv/MetersCSVUploadComponent.tsx +++ b/src/client/app/components/csv/MetersCSVUploadComponent.tsx @@ -22,7 +22,6 @@ import { selectVisibleMeterAndGroupData } from '../../redux/selectors/adminSelec * @returns CSV Meters page element */ export default function MetersCSVUploadComponent() { - const translate = useTranslate(); const [meterData, setMeterData] = React.useState(MetersCSVUploadDefaults); const [selectedFile, setSelectedFile] = React.useState(null); const [isValidFileType, setIsValidFileType] = React.useState(false); @@ -52,6 +51,7 @@ export default function MetersCSVUploadComponent() { [name]: checked })); }; + const translate = useTranslate(); const handleFileChange = (file: File) => { setSelectedFile(file); diff --git a/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx b/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx index 57bf137bc..47c990de7 100644 --- a/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx +++ b/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx @@ -27,7 +27,6 @@ import CreateMeterModalComponent from '../meters/CreateMeterModalComponent'; * @returns CSV Readings page element */ export default function ReadingsCSVUploadComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); // Check for admin status const isAdmin = useAppSelector(selectIsAdmin); @@ -88,6 +87,7 @@ export default function ReadingsCSVUploadComponent() { [name]: value === 'true' })); }; + const translate = useTranslate(); const handleFileChange = (file: File) => { if (file) { diff --git a/src/client/app/components/groups/CreateGroupModalComponent.tsx b/src/client/app/components/groups/CreateGroupModalComponent.tsx index fada30578..a2dbc47d5 100644 --- a/src/client/app/components/groups/CreateGroupModalComponent.tsx +++ b/src/client/app/components/groups/CreateGroupModalComponent.tsx @@ -40,7 +40,6 @@ import TooltipMarkerComponent from '../TooltipMarkerComponent'; * @returns Group create element */ export default function CreateGroupModalComponent() { - const translate = useTranslate(); const [createGroup] = groupsApi.useCreateGroupMutation(); // Meters state @@ -126,6 +125,7 @@ export default function CreateGroupModalComponent() { ); }, [state.area, state.areaUnit, state.name, state.deepMeters]); /* End State */ + const translate = useTranslate(); // Sums the area of the group's deep meters. It will tell the admin if any meters are omitted from the calculation, // or if any other errors are encountered. diff --git a/src/client/app/components/groups/EditGroupModalComponent.tsx b/src/client/app/components/groups/EditGroupModalComponent.tsx index ba72b81e7..9fc087537 100644 --- a/src/client/app/components/groups/EditGroupModalComponent.tsx +++ b/src/client/app/components/groups/EditGroupModalComponent.tsx @@ -57,7 +57,6 @@ interface EditGroupModalComponentProps { * @returns Group edit element */ export default function EditGroupModalComponent(props: EditGroupModalComponentProps) { - const translate = useTranslate(); const [submitGroupEdits] = groupsApi.useEditGroupMutation(); const [deleteGroup] = groupsApi.useDeleteGroupMutation(); // Meter state @@ -148,6 +147,7 @@ export default function EditGroupModalComponent(props: EditGroupModalComponentPr ); }, [groupState.area, groupState.areaUnit, groupState.name, groupState.deepMeters]); /* End State */ + const translate = useTranslate(); /* Confirm Delete Modal */ // Separate from state comment to keep everything related to the warning confirmation modal together diff --git a/src/client/app/components/groups/GroupViewComponent.tsx b/src/client/app/components/groups/GroupViewComponent.tsx index 8b30ae65d..748a3f764 100644 --- a/src/client/app/components/groups/GroupViewComponent.tsx +++ b/src/client/app/components/groups/GroupViewComponent.tsx @@ -26,7 +26,6 @@ interface GroupViewComponentProps { * @returns Group info card element */ export default function GroupViewComponent(props: GroupViewComponentProps) { - const translate = useTranslate(); // Don't check if admin since only an admin is allowed to route to this page. // Edit Modal Show @@ -46,6 +45,7 @@ export default function GroupViewComponent(props: GroupViewComponentProps) { // Set up to display the units associated with the group as the unit identifier. // unit state const unitDataById = useAppSelector(selectUnitDataById); + const translate = useTranslate(); return ( diff --git a/src/client/app/components/meters/CreateMeterModalComponent.tsx b/src/client/app/components/meters/CreateMeterModalComponent.tsx index 1c0ba7702..6301e6302 100644 --- a/src/client/app/components/meters/CreateMeterModalComponent.tsx +++ b/src/client/app/components/meters/CreateMeterModalComponent.tsx @@ -40,7 +40,6 @@ interface CreateMeterModalProps { * @returns Meter create element */ export default function CreateMeterModalComponent(props: CreateMeterModalProps): React.JSX.Element { - const translate = useTranslate(); // Tracks whether a unit/ default unit has been selected. // RTKQ Mutation to submit add meter const [submitAddMeter] = metersApi.endpoints.addMeter.useMutation(); @@ -101,6 +100,7 @@ export default function CreateMeterModalComponent(props: CreateMeterModalProps): setShowModal(false); resetState(); }; + const translate = useTranslate(); // Unlike edit, we decided to discard and inputs when you choose to leave the page. The reasoning is // that create starts from an empty template. diff --git a/src/client/app/components/meters/EditMeterModalComponent.tsx b/src/client/app/components/meters/EditMeterModalComponent.tsx index 49d3bed21..bcdea7cbd 100644 --- a/src/client/app/components/meters/EditMeterModalComponent.tsx +++ b/src/client/app/components/meters/EditMeterModalComponent.tsx @@ -43,7 +43,6 @@ interface EditMeterModalComponentProps { * @returns Meter edit element */ export default function EditMeterModalComponent(props: EditMeterModalComponentProps) { - const translate = useTranslate(); const [editMeter] = metersApi.useEditMeterMutation(); // since this selector is shared amongst many other modals, we must use a selector factory in order // to have a single selector per modal instance. Memo ensures that this is a stable reference @@ -69,6 +68,7 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr useEffect(() => { setValidMeter(isValidMeter(localMeterEdits)); }, [localMeterEdits]); /* End State */ + const translate = useTranslate(); React.useEffect(() => { if (localMeterEdits.cumulative === false) { diff --git a/src/client/app/components/meters/MeterViewComponent.tsx b/src/client/app/components/meters/MeterViewComponent.tsx index f3117e342..299b2586f 100644 --- a/src/client/app/components/meters/MeterViewComponent.tsx +++ b/src/client/app/components/meters/MeterViewComponent.tsx @@ -24,7 +24,6 @@ interface MeterViewComponentProps { * @returns Meter info card element */ export default function MeterViewComponent(props: MeterViewComponentProps) { - const translate = useTranslate(); // Edit Modal Show const [showEditModal, setShowEditModal] = useState(false); // Check for admin status @@ -43,6 +42,7 @@ export default function MeterViewComponent(props: MeterViewComponentProps) { setShowEditModal(false); }; // Only display limited data if not an admin. + const translate = useTranslate(); return (
diff --git a/src/client/app/components/router/ErrorComponent.tsx b/src/client/app/components/router/ErrorComponent.tsx index 58098df9e..e30ab4c4a 100644 --- a/src/client/app/components/router/ErrorComponent.tsx +++ b/src/client/app/components/router/ErrorComponent.tsx @@ -12,12 +12,12 @@ import { useTranslate } from '../../redux/componentHooks'; * @returns A error page that then returns to main dashboard page. */ export default function ErrorComponent() { - const translate = useTranslate(); const nav = useNavigate(); const refreshPage = () => { nav('/'); window.location.reload(); }; + const translate = useTranslate(); return ( {/* Pass div as child prop to AppLayout */} diff --git a/src/client/app/components/unit/UnitViewComponent.tsx b/src/client/app/components/unit/UnitViewComponent.tsx index 4dceca6cf..40e479ab9 100644 --- a/src/client/app/components/unit/UnitViewComponent.tsx +++ b/src/client/app/components/unit/UnitViewComponent.tsx @@ -23,7 +23,6 @@ interface UnitViewComponentProps { * @returns Unit info card element */ export default function UnitViewComponent(props: UnitViewComponentProps) { - const translate = useTranslate(); // Don't check if admin since only an admin is allow to route to this page. // Edit Modal Show @@ -36,6 +35,7 @@ export default function UnitViewComponent(props: UnitViewComponentProps) { const handleClose = () => { setShowEditModal(false); }; + const translate = useTranslate(); return (
diff --git a/src/client/app/containers/CompareChartContainer.ts b/src/client/app/containers/CompareChartContainer.ts index 277768a62..e6172c322 100644 --- a/src/client/app/containers/CompareChartContainer.ts +++ b/src/client/app/containers/CompareChartContainer.ts @@ -47,7 +47,6 @@ interface CompareChartContainerProps { * @returns The props object */ function mapStateToProps(state: RootState, ownProps: CompareChartContainerProps): any { - const translate = useTranslate(); const comparePeriod = selectComparePeriod(state); const compareTimeInterval = selectCompareTimeInterval(state); const datasets: any[] = []; @@ -134,6 +133,7 @@ function mapStateToProps(state: RootState, ownProps: CompareChartContainerProps) let previousPeriod = entity.prevUsage; let currentPeriod = entity.currUsage; const areaNormalization = selectGraphAreaNormalization(state); + const translate = useTranslate(); // Check if there is data to graph. if (previousPeriod !== null && currentPeriod !== null) { if (areaNormalization) { diff --git a/src/client/app/containers/MapChartContainer.ts b/src/client/app/containers/MapChartContainer.ts index a26f96074..22afdea4c 100644 --- a/src/client/app/containers/MapChartContainer.ts +++ b/src/client/app/containers/MapChartContainer.ts @@ -25,7 +25,6 @@ import getGraphColor from '../utils/getGraphColor'; import { useTranslate } from '../redux/componentHooks'; function mapStateToProps(state: State) { - const translate = useTranslate(); const unitID = state.graph.selectedUnit; // Map to use. let map; @@ -33,6 +32,7 @@ function mapStateToProps(state: State) { const data = []; // Holds the image to use. let image; + const translate = useTranslate(); if (state.maps.selectedMap !== 0) { const mapID = state.maps.selectedMap; if (state.maps.byMapID[mapID]) { diff --git a/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts b/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts index c71be1b74..4f8a4fb65 100644 --- a/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts +++ b/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts @@ -12,9 +12,9 @@ import {logToServer} from '../../redux/actions/logs'; import { useTranslate } from '../../redux/componentHooks'; function mapStateToProps(state: State) { - const translate = useTranslate(); const mapID = state.maps.calibratingMap; const map = state.maps.editedMaps[mapID]; + const translate = useTranslate(); const resultDisplay = (map.calibrationResult) ? `x: ${map.calibrationResult.maxError.x}%, y: ${map.calibrationResult.maxError.y}%` : translate('need.more.points'); diff --git a/src/client/app/redux/actions/conversions.ts b/src/client/app/redux/actions/conversions.ts index 21f3a23fb..768683d90 100644 --- a/src/client/app/redux/actions/conversions.ts +++ b/src/client/app/redux/actions/conversions.ts @@ -18,7 +18,6 @@ import { conversionsSlice } from '../reducers/conversions'; export function fetchConversionsDetails(): Thunk { - const translate = useTranslate(); return async (dispatch: Dispatch, getState: GetState) => { // ensure a fetch is not currently happening if (!getState().conversions.isFetching) { @@ -59,6 +58,7 @@ export function submitEditedConversion(editedConversion: t.ConversionData, shoul const conversionDataIndex = getState().conversions.submitting.findIndex(conversionData => (( conversionData.sourceId === editedConversion.sourceId) && conversionData.destinationId === editedConversion.destinationId)); + const translate = useTranslate(); // If the editedConversion is not already being submitted if (conversionDataIndex === -1) { @@ -87,6 +87,7 @@ export function submitEditedConversion(editedConversion: t.ConversionData, shoul // Add conversion to database export function addConversion(conversion: t.ConversionData): Dispatch { return async (dispatch: Dispatch) => { + const translate = useTranslate(); try { // Attempt to add conversion to database await conversionsApi.addConversion(conversion); @@ -117,6 +118,7 @@ export function deleteConversion(conversion: t.ConversionData): (dispatch: Dispa // Inform the store we are about to work on this conversion // Update the submitting state array dispatch(conversionsSlice.actions.submitEditedConversion(conversion)); + const translate = useTranslate(); try { // Attempt to delete the conversion from the database await conversionsApi.delete(conversion); diff --git a/src/client/app/redux/actions/map.ts b/src/client/app/redux/actions/map.ts index eddeb042c..d58f61f1b 100644 --- a/src/client/app/redux/actions/map.ts +++ b/src/client/app/redux/actions/map.ts @@ -232,10 +232,10 @@ export function submitCalibratingMap(): Thunk { * submit a new map to database at the end of a calibration session */ export function submitNewMap(): Thunk { - const translate = useTranslate(); return async (dispatch: Dispatch, getState: GetState) => { const mapID = getState().maps.calibratingMap; const map = getState().maps.editedMaps[mapID]; + const translate = useTranslate(); try { const acceptableMap: MapData = { ...map, @@ -267,10 +267,10 @@ export function submitNewMap(): Thunk { * @param mapID the edited map being updated at database */ export function submitEditedMap(mapID: number): Thunk { - const translate = useTranslate(); return async (dispatch: Dispatch, getState: GetState) => { const map = getState().maps.editedMaps[mapID]; dispatch(submitMapEdits(mapID)); + const translate = useTranslate(); try { const acceptableMap: MapData = { ...map, @@ -309,8 +309,8 @@ export function submitEditedMap(mapID: number): Thunk { * @param mapID map to be removed */ export function removeMap(mapID: number): Thunk { - const translate = useTranslate(); return async (dispatch: Dispatch) => { + const translate = useTranslate(); try { await mapsApi.delete(mapID); dispatch(deleteMap(mapID)); diff --git a/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts b/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts index a14482140..022cb053e 100644 --- a/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts +++ b/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts @@ -9,7 +9,6 @@ import { AppListener } from '../listenerMiddleware'; import { authApi } from '../api/authApi'; export const unauthorizedRequestListener = (startListening: AppListener) => { - const translate = useTranslate(); startListening({ predicate: action => { // Listens for rejected async thunks. if no payload then its an RTK internal call that needs to also be filtered. @@ -18,6 +17,7 @@ export const unauthorizedRequestListener = (startListening: AppListener) => { effect: (action: any, { dispatch }): void => { // Look for token failed responses from server const unAuthorizedTokenRequest = (action.payload.status === 401 || action.payload.data?.message === 'Failed to authenticate token.'); + const translate = useTranslate(); if (unAuthorizedTokenRequest) { dispatch(authApi.endpoints.logout.initiate()); showErrorNotification(translate('invalid.token.login')); diff --git a/src/client/app/redux/thunks/exportThunk.ts b/src/client/app/redux/thunks/exportThunk.ts index 9cfa8023f..7de8afcc1 100644 --- a/src/client/app/redux/thunks/exportThunk.ts +++ b/src/client/app/redux/thunks/exportThunk.ts @@ -115,7 +115,6 @@ export const exportGraphReadingsThunk = createAppThunk( export const exportRawReadings = createAppThunk( 'graph/ExportRaw', async (_arg, api) => { - const translate = useTranslate(); const state = api.getState(); if (!selectCanExport(state)) { return api.rejectWithValue('Data Fetch In Progress, Or No data'); @@ -140,6 +139,7 @@ export const exportRawReadings = createAppThunk( const fileSize = (count * 0.082 / 1000); // Decides if the readings should be exported, true if should. let shouldDownload = false; + const translate = useTranslate(); if (fileSize <= adminState.defaultWarningFileSize) { // File sizes that anyone can download without prompting so fine shouldDownload = true; diff --git a/src/client/app/utils/calibration.ts b/src/client/app/utils/calibration.ts index 2e197b2dc..e51fd3f5a 100644 --- a/src/client/app/utils/calibration.ts +++ b/src/client/app/utils/calibration.ts @@ -107,7 +107,6 @@ export function itemDisplayableOnMap(size: Dimensions, point: CartesianPoint): b * @returns true if string is GPS and false otherwise. */ export function isValidGPSInput(input: string): boolean { - const translate = useTranslate(); if (input.indexOf(',') === -1) { // if there is no comma // TODO It would be nice to tell user that comma is missing but need to check all uses to be sure don't get ''. return false; @@ -121,6 +120,7 @@ export function isValidGPSInput(input: string): boolean { const latitudeConstraint = array[latitudeIndex] >= -90 && array[latitudeIndex] <= 90; const longitudeConstraint = array[longitudeIndex] >= -180 && array[longitudeIndex] <= 180; const result = latitudeConstraint && longitudeConstraint; + const translate = useTranslate(); if (!result) { // TODO It would be nice to return the error and then notify as desired. showErrorNotification(translate('input.gps.range') + input); diff --git a/src/client/app/utils/graphics.ts b/src/client/app/utils/graphics.ts index 08f03c897..5c9eedef4 100644 --- a/src/client/app/utils/graphics.ts +++ b/src/client/app/utils/graphics.ts @@ -19,9 +19,9 @@ import { AreaUnitType } from './getAreaUnitConversion'; */ export function lineUnitLabel(selectUnitState: UnitData, currentSelectedRate: LineGraphRate, areaNormalization: boolean, selectedAreaUnit: AreaUnitType): { unitLabel: string, needsRateScaling: boolean } { - const translate = useTranslate(); let unitLabel: string = ''; let needsRateScaling = false; + const translate = useTranslate(); // Quantity and flow units have different unit labels. // Look up the type of unit if it is for quantity/flow/raw and decide what to do. // Bar graphics are always quantities. diff --git a/src/client/app/utils/input.ts b/src/client/app/utils/input.ts index da34ab302..86c8f610f 100644 --- a/src/client/app/utils/input.ts +++ b/src/client/app/utils/input.ts @@ -87,9 +87,9 @@ export const NoUnit: UnitData = { * @returns a unit to represent no unit with translated identifier */ export function noUnitTranslated(): UnitData { - const translate = useTranslate(); // Untranslated no unit. const unit = NoUnit; + const translate = useTranslate(); // Make the identifier be translated. unit.identifier = translate('unit.none'); return unit; From a045430fc1dfd5e7d088cc27c348735de3c4a2c1 Mon Sep 17 00:00:00 2001 From: Rakesh Ranga Buram Date: Fri, 25 Oct 2024 12:02:55 -0500 Subject: [PATCH 3/5] Standardize Translation Method --- src/client/app/components/AreaUnitSelectComponent.tsx | 2 +- src/client/app/components/BarChartComponent.tsx | 2 +- src/client/app/components/BarControlsComponent.tsx | 2 +- src/client/app/components/ChartLinkComponent.tsx | 2 +- src/client/app/components/ChartSelectComponent.tsx | 2 +- src/client/app/components/CompareControlsComponent.tsx | 2 +- src/client/app/components/ConfirmActionModalComponent.tsx | 2 +- src/client/app/components/DateRangeComponent.tsx | 2 +- src/client/app/components/ErrorBarComponent.tsx | 2 +- src/client/app/components/FormFileUploaderComponent.tsx | 2 +- src/client/app/components/GraphicRateMenuComponent.tsx | 2 +- src/client/app/components/HeaderButtonsComponent.tsx | 2 +- src/client/app/components/LineChartComponent.tsx | 2 +- src/client/app/components/LoginComponent.tsx | 2 +- src/client/app/components/MapChartComponent.tsx | 2 +- src/client/app/components/MapControlsComponent.tsx | 2 +- src/client/app/components/MeterAndGroupSelectComponent.tsx | 2 +- src/client/app/components/MoreOptionsComponent.tsx | 2 +- src/client/app/components/RadarChartComponent.tsx | 2 +- src/client/app/components/ReadingsPerDaySelectComponent.tsx | 2 +- src/client/app/components/ThreeDComponent.tsx | 6 +++--- src/client/app/components/ThreeDPillComponent.tsx | 2 +- src/client/app/components/TimeZoneSelect.tsx | 3 +-- src/client/app/components/TooltipHelpComponent.tsx | 3 +-- src/client/app/components/UnitSelectComponent.tsx | 2 +- src/client/app/components/UnsavedWarningComponent.tsx | 2 +- src/client/app/components/admin/PreferencesComponent.tsx | 2 +- .../app/components/admin/users/CreateUserModalComponent.tsx | 2 +- .../app/components/admin/users/EditUserModalComponent.tsx | 2 +- src/client/app/components/admin/users/UserViewComponent.tsx | 2 +- .../app/components/admin/users/UsersDetailComponent.tsx | 2 +- .../app/components/conversion/ConversionViewComponent.tsx | 2 +- .../conversion/CreateConversionModalComponent.tsx | 2 +- .../components/conversion/EditConversionModalComponent.tsx | 2 +- src/client/app/components/csv/MetersCSVUploadComponent.tsx | 2 +- .../app/components/csv/ReadingsCSVUploadComponent.tsx | 2 +- .../app/components/groups/CreateGroupModalComponent.tsx | 2 +- .../app/components/groups/EditGroupModalComponent.tsx | 2 +- src/client/app/components/groups/GroupViewComponent.tsx | 2 +- .../app/components/meters/CreateMeterModalComponent.tsx | 2 +- .../app/components/meters/EditMeterModalComponent.tsx | 2 +- src/client/app/components/meters/MeterViewComponent.tsx | 2 +- src/client/app/components/router/ErrorComponent.tsx | 2 +- src/client/app/components/unit/CreateUnitModalComponent.tsx | 2 +- src/client/app/components/unit/EditUnitModalComponent.tsx | 2 +- src/client/app/components/unit/UnitViewComponent.tsx | 2 +- src/client/app/containers/CompareChartContainer.ts | 4 ++-- src/client/app/containers/MapChartContainer.ts | 3 +-- .../containers/maps/MapCalibrationInfoDisplayContainer.ts | 3 +-- src/client/app/redux/actions/conversions.ts | 5 +---- src/client/app/redux/actions/map.ts | 5 +---- .../app/redux/middleware/unauthorizedAccesMiddleware.ts | 3 +-- src/client/app/redux/selectors/adminSelectors.ts | 3 +-- src/client/app/redux/selectors/lineChartSelectors.ts | 3 +-- src/client/app/redux/thunks/exportThunk.ts | 3 +-- src/client/app/utils/calculateCompare.ts | 4 +--- src/client/app/utils/calibration.ts | 3 +-- src/client/app/utils/graphics.ts | 4 +--- src/client/app/utils/input.ts | 3 +-- 59 files changed, 62 insertions(+), 82 deletions(-) diff --git a/src/client/app/components/AreaUnitSelectComponent.tsx b/src/client/app/components/AreaUnitSelectComponent.tsx index 58ad7266b..b3fe612f3 100644 --- a/src/client/app/components/AreaUnitSelectComponent.tsx +++ b/src/client/app/components/AreaUnitSelectComponent.tsx @@ -19,13 +19,13 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Area unit select element */ export default function AreaUnitSelectComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const graphState = useAppSelector(selectGraphState); const unitDataById = useAppSelector(selectUnitDataById); // Array of select options created from the area unit enum const unitOptions: StringSelectOption[] = []; - const translate = useTranslate(); Object.keys(AreaUnitType).forEach(unitKey => { // don't allow normalization by no unit diff --git a/src/client/app/components/BarChartComponent.tsx b/src/client/app/components/BarChartComponent.tsx index 2d7e3fad1..e3a7ed65c 100644 --- a/src/client/app/components/BarChartComponent.tsx +++ b/src/client/app/components/BarChartComponent.tsx @@ -27,6 +27,7 @@ import SpinnerComponent from './SpinnerComponent'; * @returns Plotly BarChart */ export default function BarChartComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const { barMeterDeps, barGroupDeps } = useAppSelector(selectPlotlyBarDeps); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectBarChartQueryArgs); @@ -55,7 +56,6 @@ export default function BarChartComponent() { // useQueryHooks for data fetching const datasets: Partial[] = meterReadings.concat(groupData); - const translate = useTranslate(); if (meterIsFetching || groupIsFetching) { return ; diff --git a/src/client/app/components/BarControlsComponent.tsx b/src/client/app/components/BarControlsComponent.tsx index 8b89408df..ead20b67c 100644 --- a/src/client/app/components/BarControlsComponent.tsx +++ b/src/client/app/components/BarControlsComponent.tsx @@ -15,6 +15,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns controls for the Options Ui page. */ export default function BarControlsComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // The min/max days allowed for user selection @@ -89,7 +90,6 @@ export default function BarControlsComponent() { dispatch(graphSlice.actions.updateBarDuration(moment.duration(value, 'days'))); } }; - const translate = useTranslate(); return (
diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 547abea7d..6de7aabae 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -18,6 +18,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns chartLinkComponent */ export default function ChartLinkComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const [linkTextVisible, setLinkTextVisible] = React.useState(false); const linkText = useAppSelector(selectChartLink); @@ -25,7 +26,6 @@ export default function ChartLinkComponent() { const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); const ref = React.useRef(null); - const translate = useTranslate(); const handleButtonClick = () => { // First attempt to write directly to user's clipboard. navigator.clipboard.writeText(linkText) diff --git a/src/client/app/components/ChartSelectComponent.tsx b/src/client/app/components/ChartSelectComponent.tsx index 739226a2a..494bae623 100644 --- a/src/client/app/components/ChartSelectComponent.tsx +++ b/src/client/app/components/ChartSelectComponent.tsx @@ -21,6 +21,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Chart select element */ export default function ChartSelectComponent() { + const translate = useTranslate(); const currentChartToRender = useAppSelector(selectChartToRender); const dispatch = useAppDispatch(); const [expand, setExpand] = useState(false); @@ -28,7 +29,6 @@ export default function ChartSelectComponent() { const sortedMaps = sortBy(values(mapsById).map(map => ( { value: map.id, label: map.name, isDisabled: !(map.origin && map.opposite) } as SelectOption )), 'label'); - const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/CompareControlsComponent.tsx b/src/client/app/components/CompareControlsComponent.tsx index 76d6c8c83..5b9cd3447 100644 --- a/src/client/app/components/CompareControlsComponent.tsx +++ b/src/client/app/components/CompareControlsComponent.tsx @@ -15,6 +15,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns controls for the compare page */ export default function CompareControlsComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const comparePeriod = useAppSelector(selectComparePeriod); const compareSortingOrder = useAppSelector(selectSortingOrder); @@ -25,7 +26,6 @@ export default function CompareControlsComponent() { const handleSortingButton = (sortingOrder: SortingOrder) => { dispatch(graphSlice.actions.changeCompareSortingOrder(sortingOrder)); }; - const translate = useTranslate(); return (
diff --git a/src/client/app/components/ConfirmActionModalComponent.tsx b/src/client/app/components/ConfirmActionModalComponent.tsx index b6aa27e74..9f15d58b7 100644 --- a/src/client/app/components/ConfirmActionModalComponent.tsx +++ b/src/client/app/components/ConfirmActionModalComponent.tsx @@ -41,10 +41,10 @@ interface ConfirmActionModalComponentProps { * @returns A modal component that executes the actionFunction on confirmation and handleClose on rejection. */ export default function ConfirmActionModalComponent(props: ConfirmActionModalComponentProps) { + const translate = useTranslate(); const handleClose = () => { props.handleClose(); }; - const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/DateRangeComponent.tsx b/src/client/app/components/DateRangeComponent.tsx index 8cc374d33..033b311e3 100644 --- a/src/client/app/components/DateRangeComponent.tsx +++ b/src/client/app/components/DateRangeComponent.tsx @@ -22,6 +22,7 @@ import { ChartTypes } from '../types/redux/graph'; * @returns Date Range Calendar Picker */ export default function DateRangeComponent() { + const translate = useTranslate(); const dispatch: Dispatch = useAppDispatch(); const queryTimeInterval = useAppSelector(selectQueryTimeInterval); const locale = useAppSelector(selectSelectedLanguage); @@ -32,7 +33,6 @@ export default function DateRangeComponent() { dispatch(updateTimeInterval(dateRangeToTimeInterval(value))); dispatch(changeSliderRange(dateRangeToTimeInterval(value))); }; - const translate = useTranslate(); return ( diff --git a/src/client/app/components/ErrorBarComponent.tsx b/src/client/app/components/ErrorBarComponent.tsx index 9fe1f8282..957adb04b 100644 --- a/src/client/app/components/ErrorBarComponent.tsx +++ b/src/client/app/components/ErrorBarComponent.tsx @@ -13,9 +13,9 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Error Bar checkbox with tooltip and label */ export default function ErrorBarComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const showMinMax = useAppSelector(selectShowMinMax); - const translate = useTranslate(); return (
diff --git a/src/client/app/components/FormFileUploaderComponent.tsx b/src/client/app/components/FormFileUploaderComponent.tsx index 2d90906cf..714001f63 100644 --- a/src/client/app/components/FormFileUploaderComponent.tsx +++ b/src/client/app/components/FormFileUploaderComponent.tsx @@ -17,11 +17,11 @@ interface FileUploader { * @returns File uploader element */ export default function FileUploaderComponent(props: FileUploader) { + const translate = useTranslate(); const handleFileChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0] || null; props.onFileChange(file); }; - const translate = useTranslate(); return ( diff --git a/src/client/app/components/GraphicRateMenuComponent.tsx b/src/client/app/components/GraphicRateMenuComponent.tsx index 9d8717964..febe41352 100644 --- a/src/client/app/components/GraphicRateMenuComponent.tsx +++ b/src/client/app/components/GraphicRateMenuComponent.tsx @@ -19,6 +19,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Rate selection element */ export default function GraphicRateMenuComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // Graph state @@ -48,7 +49,6 @@ export default function GraphicRateMenuComponent() { } // Array of select options created from the rates const rateOptions: SelectOption[] = []; - const translate = useTranslate(); //Loop over our rates object to create the selects for the dropdown Object.entries(LineGraphRates).forEach(([rateKey, rateValue]) => { diff --git a/src/client/app/components/HeaderButtonsComponent.tsx b/src/client/app/components/HeaderButtonsComponent.tsx index fc9a67b47..58f41e53e 100644 --- a/src/client/app/components/HeaderButtonsComponent.tsx +++ b/src/client/app/components/HeaderButtonsComponent.tsx @@ -25,6 +25,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Header buttons element */ export default function HeaderButtonsComponent() { + const translate = useTranslate(); const [logout] = authApi.useLogoutMutation(); const dispatch = useAppDispatch(); // Get the current page so know which one should not be shown in menu. @@ -74,7 +75,6 @@ export default function HeaderButtonsComponent() { // TODO Re-implement AFTER RTK Migration // hard-coded for the time being. Rework w/admin pages const unsavedChangesState = false; - const translate = useTranslate(); // Must update in case the version was not set when the page was loaded. diff --git a/src/client/app/components/LineChartComponent.tsx b/src/client/app/components/LineChartComponent.tsx index adf658d3b..95c0d294e 100644 --- a/src/client/app/components/LineChartComponent.tsx +++ b/src/client/app/components/LineChartComponent.tsx @@ -24,6 +24,7 @@ import SpinnerComponent from './SpinnerComponent'; * @returns plotlyLine graphic */ export default function LineChartComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // get current data fetching arguments const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectLineChartQueryArgs); @@ -66,7 +67,6 @@ export default function LineChartComponent() { // Check if there is at least one valid graph const enoughData = data.find(data => data.x!.length > 1); - const translate = useTranslate(); // Customize the layout of the plot // See https://community.plotly.com/t/replacing-an-empty-graph-with-a-message/31497 for showing text not plot. if (data.length === 0) { diff --git a/src/client/app/components/LoginComponent.tsx b/src/client/app/components/LoginComponent.tsx index 399199312..d182fd13d 100644 --- a/src/client/app/components/LoginComponent.tsx +++ b/src/client/app/components/LoginComponent.tsx @@ -16,6 +16,7 @@ import { useTranslate } from '../redux/componentHooks'; * @returns The login page for users or admins. */ export default function LoginComponent() { + const translate = useTranslate(); // Local State const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -28,7 +29,6 @@ export default function LoginComponent() { // The naming of the returned objects is arbitrary // Equivalent Auto-Derived Method const [login] = authApi.endpoints.login.useMutation(); // authApi.useLoginMutation() - const translate = useTranslate(); const handleSubmit = async (event: React.MouseEvent) => { event.preventDefault(); diff --git a/src/client/app/components/MapChartComponent.tsx b/src/client/app/components/MapChartComponent.tsx index a0e64a35d..baf02d3b4 100644 --- a/src/client/app/components/MapChartComponent.tsx +++ b/src/client/app/components/MapChartComponent.tsx @@ -39,6 +39,7 @@ import SpinnerComponent from './SpinnerComponent'; * @returns map component */ export default function MapChartComponent() { + const translate = useTranslate(); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectMapChartQueryArgs); const { data: meterReadings, isLoading: meterIsFetching } = readingsApi.useBarQuery(meterArgs, { skip: meterShouldSkip }); const { data: groupData, isLoading: groupIsFetching } = readingsApi.useBarQuery(groupArgs, { skip: groupShouldSkip }); @@ -70,7 +71,6 @@ export default function MapChartComponent() { const data = []; // Holds the image to use. let image; - const translate = useTranslate(); if (selectedMap !== 0) { const mapID = selectedMap; if (byMapID[mapID]) { diff --git a/src/client/app/components/MapControlsComponent.tsx b/src/client/app/components/MapControlsComponent.tsx index 73849f0d0..9a3a10ddc 100644 --- a/src/client/app/components/MapControlsComponent.tsx +++ b/src/client/app/components/MapControlsComponent.tsx @@ -15,6 +15,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns Map page controls */ export default function MapControlsComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const barDuration = useAppSelector(selectMapBarWidthDays); @@ -23,7 +24,6 @@ export default function MapControlsComponent() { }; const barDurationDays = barDuration.asDays(); - const translate = useTranslate(); return (
diff --git a/src/client/app/components/MeterAndGroupSelectComponent.tsx b/src/client/app/components/MeterAndGroupSelectComponent.tsx index b85001741..67f0b8015 100644 --- a/src/client/app/components/MeterAndGroupSelectComponent.tsx +++ b/src/client/app/components/MeterAndGroupSelectComponent.tsx @@ -25,6 +25,7 @@ import { selectAnythingFetching } from '../redux/selectors/apiSelectors'; * @returns A React-Select component. */ export default function MeterAndGroupSelectComponent(props: MeterAndGroupSelectProps) { + const translate = useTranslate(); const dispatch = useAppDispatch(); const { meterGroupedOptions, groupsGroupedOptions, allSelectedMeterValues, allSelectedGroupValues } = useAppSelector(selectMeterGroupSelectData); const somethingIsFetching = useAppSelector(selectAnythingFetching); @@ -39,7 +40,6 @@ export default function MeterAndGroupSelectComponent(props: MeterAndGroupSelectP const newMetersOrGroups = newValues.map(option => option.value); dispatch(updateSelectedMetersOrGroups({ newMetersOrGroups, meta })); }; - const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/MoreOptionsComponent.tsx b/src/client/app/components/MoreOptionsComponent.tsx index be5047594..bdc860ab3 100644 --- a/src/client/app/components/MoreOptionsComponent.tsx +++ b/src/client/app/components/MoreOptionsComponent.tsx @@ -22,13 +22,13 @@ import { useTranslate } from '../redux/componentHooks'; * @returns Custom Modal depending on selected graph type */ export default function MoreOptionsComponent() { + const translate = useTranslate(); const chartToRender = useAppSelector(selectChartToRender); const [showModal, setShowModal] = useState(false); const handleShow = () => setShowModal(true); const handleClose = () => { setShowModal(false); }; - const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/RadarChartComponent.tsx b/src/client/app/components/RadarChartComponent.tsx index 5c382bc17..3ff51879b 100644 --- a/src/client/app/components/RadarChartComponent.tsx +++ b/src/client/app/components/RadarChartComponent.tsx @@ -29,6 +29,7 @@ import SpinnerComponent from './SpinnerComponent'; * @returns radar plotly component */ export default function RadarChartComponent() { + const translate = useTranslate(); const { meterArgs, groupArgs, meterShouldSkip, groupShouldSkip } = useAppSelector(selectRadarChartQueryArgs); const { data: meterReadings, isLoading: meterIsLoading } = readingsApi.useLineQuery(meterArgs, { skip: meterShouldSkip }); const { data: groupData, isLoading: groupIsLoading } = readingsApi.useLineQuery(groupArgs, { skip: groupShouldSkip }); @@ -66,7 +67,6 @@ export default function RadarChartComponent() { } // The rate will be 1 if it is per hour (since state readings are per hour) or no rate scaling so no change. const rateScaling = needsRateScaling ? currentSelectedRate.rate : 1; - const translate = useTranslate(); // Add all valid data from existing meters to the radar plot for (const meterID of selectedMeters) { diff --git a/src/client/app/components/ReadingsPerDaySelectComponent.tsx b/src/client/app/components/ReadingsPerDaySelectComponent.tsx index c7e7511b6..40a56cbd0 100644 --- a/src/client/app/components/ReadingsPerDaySelectComponent.tsx +++ b/src/client/app/components/ReadingsPerDaySelectComponent.tsx @@ -18,6 +18,7 @@ import TooltipMarkerComponent from './TooltipMarkerComponent'; * @returns A Select menu with Readings per day options. */ export default function ReadingsPerDaySelect() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const readingInterval = useAppSelector(selectThreeDReadingInterval); const { args, shouldSkipQuery } = useAppSelector(selectThreeDQueryArgs); @@ -29,7 +30,6 @@ export default function ReadingsPerDaySelect() { ...selectReadingsPerDaySelectData(currentData ?? stableEmptyThreeDReadings, readingInterval) }) }); - const translate = useTranslate(); return (
diff --git a/src/client/app/components/ThreeDComponent.tsx b/src/client/app/components/ThreeDComponent.tsx index f56970755..4790be383 100644 --- a/src/client/app/components/ThreeDComponent.tsx +++ b/src/client/app/components/ThreeDComponent.tsx @@ -32,6 +32,7 @@ import Locales from '../types/locales'; * @returns 3D Plotly 3D Surface Graph */ export default function ThreeDComponent() { + const translate = useTranslate(); const { args, shouldSkipQuery } = useAppSelector(selectThreeDQueryArgs); const { data, isFetching } = readingsApi.endpoints.threeD.useQuery(args, { skip: shouldSkipQuery }); const meterDataById = useAppSelector(selectMeterDataById); @@ -46,7 +47,6 @@ export default function ThreeDComponent() { const threeDData = data; let layout = {}; let dataToRender = null; - const translate = useTranslate(); if (!meterOrGroupID) { @@ -111,6 +111,7 @@ function formatThreeDData( graphState: GraphState, unitDataById: UnitDataById ) { + const translate = useTranslate(); // Initialize Plotly Data const xDataToRender: string[] = []; const yDataToRender: string[] = []; @@ -125,7 +126,6 @@ function formatThreeDData( const currentSelectedRate = graphState.lineGraphRate; let unitLabel = ''; let needsRateScaling = false; - const translate = useTranslate(); if (graphingUnit !== -99) { const selectUnitState = unitDataById[graphState.selectedUnit]; if (selectUnitState !== undefined) { @@ -229,12 +229,12 @@ function setHelpLayout(helpText: string = 'Help Text Goes Here', fontSize: numbe * @returns plotly layout object. */ function setThreeDLayout(zLabelText: string = 'Resource Usage', yDataToRender: string[]) { + const translate = useTranslate(); // Convert date strings to JavaScript Date objects and then get dataRange const dateObjects = yDataToRender.map(dateStr => new Date(dateStr)); const dataMin = Math.min(...dateObjects.map(date => date.getTime())); const dataMax = Math.max(...dateObjects.map(date => date.getTime())); const dataRange = dataMax - dataMin; - const translate = useTranslate(); //Calculate nTicks for small num of days on y-axis; possibly a better way let nTicks, dTick = 'd1'; diff --git a/src/client/app/components/ThreeDPillComponent.tsx b/src/client/app/components/ThreeDPillComponent.tsx index 3f8610cf7..cbc637e7a 100644 --- a/src/client/app/components/ThreeDPillComponent.tsx +++ b/src/client/app/components/ThreeDPillComponent.tsx @@ -17,6 +17,7 @@ import { useTranslate } from '../redux/componentHooks'; * @returns List of selected groups and meters as reactstrap Pills Badges */ export default function ThreeDPillComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const meterDataById = useAppSelector(selectMeterDataById); const groupDataById = useAppSelector(selectGroupDataById); @@ -81,7 +82,6 @@ export default function ThreeDPillComponent() { ); }); }; - const translate = useTranslate(); return (
diff --git a/src/client/app/components/TimeZoneSelect.tsx b/src/client/app/components/TimeZoneSelect.tsx index 50c3e5d9b..9abc63b95 100644 --- a/src/client/app/components/TimeZoneSelect.tsx +++ b/src/client/app/components/TimeZoneSelect.tsx @@ -15,7 +15,7 @@ interface TimeZoneSelectProps { } const TimeZoneSelect: React.FC = ({ current, handleClick }) => { - + const translate = useTranslate(); const getTimeZones = () => { const zoneNames = moment.tz.names(); return zoneNames.map(zoneName => { @@ -24,7 +24,6 @@ const TimeZoneSelect: React.FC = ({ current, handleClick }) return { value: zoneName, label: `${zoneName} (${abbrev})` }; }); }; - const translate = useTranslate(); const resetTimeZone = [{ value: null, label: translate('timezone.no') }]; const options = [...resetTimeZone, ...getTimeZones()]; diff --git a/src/client/app/components/TooltipHelpComponent.tsx b/src/client/app/components/TooltipHelpComponent.tsx index 5c08947bb..573d4470b 100644 --- a/src/client/app/components/TooltipHelpComponent.tsx +++ b/src/client/app/components/TooltipHelpComponent.tsx @@ -23,7 +23,7 @@ export default function TooltipHelpComponent(props: TooltipHelpProps) { /** * @returns JSX to create the help icons with links */ - + const translate = useTranslate(); const version = useAppSelector(selectOEDVersion); const helpUrl = useAppSelector(selectHelpUrl); @@ -72,7 +72,6 @@ export default function TooltipHelpComponent(props: TooltipHelpProps) { 'help.groups.groupview': { link: `${helpUrl}/groupViewing/` }, 'help.meters.meterview': { link: `${helpUrl}/meterViewing/` } }; - const translate = useTranslate(); return (
diff --git a/src/client/app/components/UnitSelectComponent.tsx b/src/client/app/components/UnitSelectComponent.tsx index a4689a10a..f07e478de 100644 --- a/src/client/app/components/UnitSelectComponent.tsx +++ b/src/client/app/components/UnitSelectComponent.tsx @@ -19,6 +19,7 @@ import { selectUnitDataById, unitsApi } from '../redux/api/unitsApi'; * @returns A React-Select component for UI Options Panel */ export default function UnitSelectComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const unitSelectOptions = useAppSelector(selectUnitSelectData); const selectedUnitID = useAppSelector(selectSelectedUnit); @@ -38,7 +39,6 @@ export default function UnitSelectComponent() { } const onChange = (newValue: SelectOption) => dispatch(graphSlice.actions.updateSelectedUnit(newValue?.value)); - const translate = useTranslate(); return (
diff --git a/src/client/app/components/UnsavedWarningComponent.tsx b/src/client/app/components/UnsavedWarningComponent.tsx index d68254c93..313a288d9 100644 --- a/src/client/app/components/UnsavedWarningComponent.tsx +++ b/src/client/app/components/UnsavedWarningComponent.tsx @@ -25,9 +25,9 @@ export interface UnsavedWarningProps { * @returns Component that prompts before navigating away from current page */ export function UnsavedWarningComponent(props: UnsavedWarningProps) { + const translate = useTranslate(); const { hasUnsavedChanges, submitChanges, changes } = props; const blocker = useBlocker(hasUnsavedChanges); - const translate = useTranslate(); const handleSubmit = async () => { submitChanges(changes) .unwrap() diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index 5628f5e17..ffc2717cb 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -23,6 +23,7 @@ import { defaultAdminState } from '../../redux/slices/adminSlice'; * @returns Preferences Component for Administrative use */ export default function PreferencesComponent() { + const translate = useTranslate(); const { data: adminPreferences = defaultAdminState } = preferencesApi.useGetPreferencesQuery(); const [localAdminPref, setLocalAdminPref] = React.useState(cloneDeep(adminPreferences)); const [submitPreferences] = preferencesApi.useSubmitPreferencesMutation(); @@ -41,7 +42,6 @@ export default function PreferencesComponent() { const discardChanges = () => { setLocalAdminPref(cloneDeep(adminPreferences)); }; - const translate = useTranslate(); return (
diff --git a/src/client/app/components/admin/users/CreateUserModalComponent.tsx b/src/client/app/components/admin/users/CreateUserModalComponent.tsx index 2319f0b29..0594c73ff 100644 --- a/src/client/app/components/admin/users/CreateUserModalComponent.tsx +++ b/src/client/app/components/admin/users/CreateUserModalComponent.tsx @@ -21,6 +21,7 @@ import { tooltipBaseStyle } from '../../../styles/modalStyle'; * @returns CreateUserModal component */ export default function CreateUserModal() { + const translate = useTranslate(); // create user form state and use the defaults const [userDetails, setUserDetails] = useState(userDefaults); @@ -85,7 +86,6 @@ export default function CreateUserModal() { setShowModal(false); }; // End Modal show/close - const translate = useTranslate(); const handleSubmit = async () => { const newUser: User = { username: userDetails.username, role: userDetails.role, password: userDetails.password, note: userDetails.note }; diff --git a/src/client/app/components/admin/users/EditUserModalComponent.tsx b/src/client/app/components/admin/users/EditUserModalComponent.tsx index fad2a83f6..4568b2704 100644 --- a/src/client/app/components/admin/users/EditUserModalComponent.tsx +++ b/src/client/app/components/admin/users/EditUserModalComponent.tsx @@ -29,6 +29,7 @@ interface EditUserModalComponentProps { * @returns User edit element */ export default function EditUserModalComponent(props: EditUserModalComponentProps) { + const translate = useTranslate(); // get current logged in user const currentLoggedInUser = useAppSelector(selectCurrentUserProfile) as User; @@ -85,7 +86,6 @@ export default function EditUserModalComponent(props: EditUserModalComponentProp confirmPassword: '' })); }; - const translate = useTranslate(); /* Confirm Delete Modal */ // Separate from state comment to keep everything related to the warning confirmation modal together diff --git a/src/client/app/components/admin/users/UserViewComponent.tsx b/src/client/app/components/admin/users/UserViewComponent.tsx index 099d369c0..0420c3032 100644 --- a/src/client/app/components/admin/users/UserViewComponent.tsx +++ b/src/client/app/components/admin/users/UserViewComponent.tsx @@ -21,6 +21,7 @@ interface UserViewComponentProps { * @returns User card element */ export default function UserViewComponent(props: UserViewComponentProps) { + const translate = useTranslate(); const [showEditModal, setShowEditModal] = useState(false); const handleShow = () => { @@ -30,7 +31,6 @@ export default function UserViewComponent(props: UserViewComponentProps) { const handleClose = () => { setShowEditModal(false); }; - const translate = useTranslate(); return (
diff --git a/src/client/app/components/admin/users/UsersDetailComponent.tsx b/src/client/app/components/admin/users/UsersDetailComponent.tsx index 83e819d00..c01c382db 100644 --- a/src/client/app/components/admin/users/UsersDetailComponent.tsx +++ b/src/client/app/components/admin/users/UsersDetailComponent.tsx @@ -22,8 +22,8 @@ const tooltipStyle = { * @returns User Detail element */ export default function UserDetailComponent() { - const { data: users = stableEmptyUsers } = userApi.useGetUsersQuery(); const translate = useTranslate(); + const { data: users = stableEmptyUsers } = userApi.useGetUsersQuery(); return (
diff --git a/src/client/app/components/conversion/ConversionViewComponent.tsx b/src/client/app/components/conversion/ConversionViewComponent.tsx index 749c577cb..c63642372 100644 --- a/src/client/app/components/conversion/ConversionViewComponent.tsx +++ b/src/client/app/components/conversion/ConversionViewComponent.tsx @@ -25,6 +25,7 @@ interface ConversionViewComponentProps { * @returns Single conversion element */ export default function ConversionViewComponent(props: ConversionViewComponentProps) { + const translate = useTranslate(); // Don't check if admin since only an admin is allow to route to this page. // Edit Modal Show @@ -44,7 +45,6 @@ export default function ConversionViewComponent(props: ConversionViewComponentPr unitDataById[props.conversion.destinationId]?.identifier); // Unlike the details component, we don't check if units are loaded since must come through that page. - const translate = useTranslate(); return (
diff --git a/src/client/app/components/conversion/CreateConversionModalComponent.tsx b/src/client/app/components/conversion/CreateConversionModalComponent.tsx index f383555c2..cb4ba8bd1 100644 --- a/src/client/app/components/conversion/CreateConversionModalComponent.tsx +++ b/src/client/app/components/conversion/CreateConversionModalComponent.tsx @@ -23,6 +23,7 @@ import TooltipMarkerComponent from '../TooltipMarkerComponent'; * @returns Conversion create element */ export default function CreateConversionModalComponent() { + const translate = useTranslate(); const [addConversionMutation] = conversionsApi.useAddConversionMutation(); // Want units in sorted order by identifier regardless of case. @@ -98,7 +99,6 @@ export default function CreateConversionModalComponent() { ...tooltipBaseStyle, tooltipCreateConversionView: 'help.admin.conversioncreate' }; - const translate = useTranslate(); return ( <> diff --git a/src/client/app/components/conversion/EditConversionModalComponent.tsx b/src/client/app/components/conversion/EditConversionModalComponent.tsx index 155aa8464..156f52d74 100644 --- a/src/client/app/components/conversion/EditConversionModalComponent.tsx +++ b/src/client/app/components/conversion/EditConversionModalComponent.tsx @@ -34,6 +34,7 @@ interface EditConversionModalComponentProps { * @returns Conversion edit element */ export default function EditConversionModalComponent(props: EditConversionModalComponentProps) { + const translate = useTranslate(); const [editConversion] = conversionsApi.useEditConversionMutation(); const [deleteConversion] = conversionsApi.useDeleteConversionMutation(); const unitDataById = useAppSelector(selectUnitDataById); @@ -57,7 +58,6 @@ export default function EditConversionModalComponent(props: EditConversionModalC setState({ ...state, [e.target.name]: Number(e.target.value) }); }; /* End State */ - const translate = useTranslate(); /* Confirm Delete Modal */ // Separate from state comment to keep everything related to the warning confirmation modal together diff --git a/src/client/app/components/csv/MetersCSVUploadComponent.tsx b/src/client/app/components/csv/MetersCSVUploadComponent.tsx index eee66614e..e7a6b4dbf 100644 --- a/src/client/app/components/csv/MetersCSVUploadComponent.tsx +++ b/src/client/app/components/csv/MetersCSVUploadComponent.tsx @@ -22,6 +22,7 @@ import { selectVisibleMeterAndGroupData } from '../../redux/selectors/adminSelec * @returns CSV Meters page element */ export default function MetersCSVUploadComponent() { + const translate = useTranslate(); const [meterData, setMeterData] = React.useState(MetersCSVUploadDefaults); const [selectedFile, setSelectedFile] = React.useState(null); const [isValidFileType, setIsValidFileType] = React.useState(false); @@ -51,7 +52,6 @@ export default function MetersCSVUploadComponent() { [name]: checked })); }; - const translate = useTranslate(); const handleFileChange = (file: File) => { setSelectedFile(file); diff --git a/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx b/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx index 47c990de7..57bf137bc 100644 --- a/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx +++ b/src/client/app/components/csv/ReadingsCSVUploadComponent.tsx @@ -27,6 +27,7 @@ import CreateMeterModalComponent from '../meters/CreateMeterModalComponent'; * @returns CSV Readings page element */ export default function ReadingsCSVUploadComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); // Check for admin status const isAdmin = useAppSelector(selectIsAdmin); @@ -87,7 +88,6 @@ export default function ReadingsCSVUploadComponent() { [name]: value === 'true' })); }; - const translate = useTranslate(); const handleFileChange = (file: File) => { if (file) { diff --git a/src/client/app/components/groups/CreateGroupModalComponent.tsx b/src/client/app/components/groups/CreateGroupModalComponent.tsx index a2dbc47d5..fada30578 100644 --- a/src/client/app/components/groups/CreateGroupModalComponent.tsx +++ b/src/client/app/components/groups/CreateGroupModalComponent.tsx @@ -40,6 +40,7 @@ import TooltipMarkerComponent from '../TooltipMarkerComponent'; * @returns Group create element */ export default function CreateGroupModalComponent() { + const translate = useTranslate(); const [createGroup] = groupsApi.useCreateGroupMutation(); // Meters state @@ -125,7 +126,6 @@ export default function CreateGroupModalComponent() { ); }, [state.area, state.areaUnit, state.name, state.deepMeters]); /* End State */ - const translate = useTranslate(); // Sums the area of the group's deep meters. It will tell the admin if any meters are omitted from the calculation, // or if any other errors are encountered. diff --git a/src/client/app/components/groups/EditGroupModalComponent.tsx b/src/client/app/components/groups/EditGroupModalComponent.tsx index 9fc087537..ba72b81e7 100644 --- a/src/client/app/components/groups/EditGroupModalComponent.tsx +++ b/src/client/app/components/groups/EditGroupModalComponent.tsx @@ -57,6 +57,7 @@ interface EditGroupModalComponentProps { * @returns Group edit element */ export default function EditGroupModalComponent(props: EditGroupModalComponentProps) { + const translate = useTranslate(); const [submitGroupEdits] = groupsApi.useEditGroupMutation(); const [deleteGroup] = groupsApi.useDeleteGroupMutation(); // Meter state @@ -147,7 +148,6 @@ export default function EditGroupModalComponent(props: EditGroupModalComponentPr ); }, [groupState.area, groupState.areaUnit, groupState.name, groupState.deepMeters]); /* End State */ - const translate = useTranslate(); /* Confirm Delete Modal */ // Separate from state comment to keep everything related to the warning confirmation modal together diff --git a/src/client/app/components/groups/GroupViewComponent.tsx b/src/client/app/components/groups/GroupViewComponent.tsx index 748a3f764..8b30ae65d 100644 --- a/src/client/app/components/groups/GroupViewComponent.tsx +++ b/src/client/app/components/groups/GroupViewComponent.tsx @@ -26,6 +26,7 @@ interface GroupViewComponentProps { * @returns Group info card element */ export default function GroupViewComponent(props: GroupViewComponentProps) { + const translate = useTranslate(); // Don't check if admin since only an admin is allowed to route to this page. // Edit Modal Show @@ -45,7 +46,6 @@ export default function GroupViewComponent(props: GroupViewComponentProps) { // Set up to display the units associated with the group as the unit identifier. // unit state const unitDataById = useAppSelector(selectUnitDataById); - const translate = useTranslate(); return ( diff --git a/src/client/app/components/meters/CreateMeterModalComponent.tsx b/src/client/app/components/meters/CreateMeterModalComponent.tsx index 6301e6302..1c0ba7702 100644 --- a/src/client/app/components/meters/CreateMeterModalComponent.tsx +++ b/src/client/app/components/meters/CreateMeterModalComponent.tsx @@ -40,6 +40,7 @@ interface CreateMeterModalProps { * @returns Meter create element */ export default function CreateMeterModalComponent(props: CreateMeterModalProps): React.JSX.Element { + const translate = useTranslate(); // Tracks whether a unit/ default unit has been selected. // RTKQ Mutation to submit add meter const [submitAddMeter] = metersApi.endpoints.addMeter.useMutation(); @@ -100,7 +101,6 @@ export default function CreateMeterModalComponent(props: CreateMeterModalProps): setShowModal(false); resetState(); }; - const translate = useTranslate(); // Unlike edit, we decided to discard and inputs when you choose to leave the page. The reasoning is // that create starts from an empty template. diff --git a/src/client/app/components/meters/EditMeterModalComponent.tsx b/src/client/app/components/meters/EditMeterModalComponent.tsx index bcdea7cbd..49d3bed21 100644 --- a/src/client/app/components/meters/EditMeterModalComponent.tsx +++ b/src/client/app/components/meters/EditMeterModalComponent.tsx @@ -43,6 +43,7 @@ interface EditMeterModalComponentProps { * @returns Meter edit element */ export default function EditMeterModalComponent(props: EditMeterModalComponentProps) { + const translate = useTranslate(); const [editMeter] = metersApi.useEditMeterMutation(); // since this selector is shared amongst many other modals, we must use a selector factory in order // to have a single selector per modal instance. Memo ensures that this is a stable reference @@ -68,7 +69,6 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr useEffect(() => { setValidMeter(isValidMeter(localMeterEdits)); }, [localMeterEdits]); /* End State */ - const translate = useTranslate(); React.useEffect(() => { if (localMeterEdits.cumulative === false) { diff --git a/src/client/app/components/meters/MeterViewComponent.tsx b/src/client/app/components/meters/MeterViewComponent.tsx index 299b2586f..f3117e342 100644 --- a/src/client/app/components/meters/MeterViewComponent.tsx +++ b/src/client/app/components/meters/MeterViewComponent.tsx @@ -24,6 +24,7 @@ interface MeterViewComponentProps { * @returns Meter info card element */ export default function MeterViewComponent(props: MeterViewComponentProps) { + const translate = useTranslate(); // Edit Modal Show const [showEditModal, setShowEditModal] = useState(false); // Check for admin status @@ -42,7 +43,6 @@ export default function MeterViewComponent(props: MeterViewComponentProps) { setShowEditModal(false); }; // Only display limited data if not an admin. - const translate = useTranslate(); return (
diff --git a/src/client/app/components/router/ErrorComponent.tsx b/src/client/app/components/router/ErrorComponent.tsx index e30ab4c4a..58098df9e 100644 --- a/src/client/app/components/router/ErrorComponent.tsx +++ b/src/client/app/components/router/ErrorComponent.tsx @@ -12,12 +12,12 @@ import { useTranslate } from '../../redux/componentHooks'; * @returns A error page that then returns to main dashboard page. */ export default function ErrorComponent() { + const translate = useTranslate(); const nav = useNavigate(); const refreshPage = () => { nav('/'); window.location.reload(); }; - const translate = useTranslate(); return ( {/* Pass div as child prop to AppLayout */} diff --git a/src/client/app/components/unit/CreateUnitModalComponent.tsx b/src/client/app/components/unit/CreateUnitModalComponent.tsx index e6e06023a..621f71b23 100644 --- a/src/client/app/components/unit/CreateUnitModalComponent.tsx +++ b/src/client/app/components/unit/CreateUnitModalComponent.tsx @@ -21,8 +21,8 @@ import { showSuccessNotification, showErrorNotification } from '../../utils/noti * @returns Unit create element */ export default function CreateUnitModalComponent() { - const [submitCreateUnit] = unitsApi.useAddUnitMutation(); const translate = useTranslate(); + const [submitCreateUnit] = unitsApi.useAddUnitMutation(); const defaultValues = { name: '', diff --git a/src/client/app/components/unit/EditUnitModalComponent.tsx b/src/client/app/components/unit/EditUnitModalComponent.tsx index 137d24345..046a7e0b1 100644 --- a/src/client/app/components/unit/EditUnitModalComponent.tsx +++ b/src/client/app/components/unit/EditUnitModalComponent.tsx @@ -37,9 +37,9 @@ interface EditUnitModalComponentProps { * @returns Unit edit element */ export default function EditUnitModalComponent(props: EditUnitModalComponentProps) { + const translate = useTranslate(); const [submitEditedUnit] = unitsApi.useEditUnitMutation(); const [deleteUnit] = unitsApi.useDeleteUnitMutation(); - const translate = useTranslate(); // Set existing unit values const values = { ...props.unit }; diff --git a/src/client/app/components/unit/UnitViewComponent.tsx b/src/client/app/components/unit/UnitViewComponent.tsx index 40e479ab9..d475a2347 100644 --- a/src/client/app/components/unit/UnitViewComponent.tsx +++ b/src/client/app/components/unit/UnitViewComponent.tsx @@ -24,6 +24,7 @@ interface UnitViewComponentProps { */ export default function UnitViewComponent(props: UnitViewComponentProps) { // Don't check if admin since only an admin is allow to route to this page. + const translate = useTranslate(); // Edit Modal Show const [showEditModal, setShowEditModal] = useState(false); @@ -35,7 +36,6 @@ export default function UnitViewComponent(props: UnitViewComponentProps) { const handleClose = () => { setShowEditModal(false); }; - const translate = useTranslate(); return (
diff --git a/src/client/app/containers/CompareChartContainer.ts b/src/client/app/containers/CompareChartContainer.ts index e6172c322..139478a02 100644 --- a/src/client/app/containers/CompareChartContainer.ts +++ b/src/client/app/containers/CompareChartContainer.ts @@ -6,7 +6,8 @@ import { connect } from 'react-redux'; import { getComparePeriodLabels, getCompareChangeSummary, calculateCompareShift } from '../utils/calculateCompare'; -import { useTranslate } from '../redux/componentHooks'; +// When this container gets converted to component,migrate to useTranslate() from componentHooks.ts +import translate from '../utils/translate'; import Plot from 'react-plotly.js'; import Locales from '../types/locales'; import * as moment from 'moment'; @@ -133,7 +134,6 @@ function mapStateToProps(state: RootState, ownProps: CompareChartContainerProps) let previousPeriod = entity.prevUsage; let currentPeriod = entity.currUsage; const areaNormalization = selectGraphAreaNormalization(state); - const translate = useTranslate(); // Check if there is data to graph. if (previousPeriod !== null && currentPeriod !== null) { if (areaNormalization) { diff --git a/src/client/app/containers/MapChartContainer.ts b/src/client/app/containers/MapChartContainer.ts index 22afdea4c..45a8049c6 100644 --- a/src/client/app/containers/MapChartContainer.ts +++ b/src/client/app/containers/MapChartContainer.ts @@ -22,7 +22,7 @@ import { } from '../utils/calibration'; import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion'; import getGraphColor from '../utils/getGraphColor'; -import { useTranslate } from '../redux/componentHooks'; +import translate from '../utils/translate'; function mapStateToProps(state: State) { const unitID = state.graph.selectedUnit; @@ -32,7 +32,6 @@ function mapStateToProps(state: State) { const data = []; // Holds the image to use. let image; - const translate = useTranslate(); if (state.maps.selectedMap !== 0) { const mapID = state.maps.selectedMap; if (state.maps.byMapID[mapID]) { diff --git a/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts b/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts index 4f8a4fb65..94e27983c 100644 --- a/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts +++ b/src/client/app/containers/maps/MapCalibrationInfoDisplayContainer.ts @@ -9,12 +9,11 @@ import MapCalibrationInfoDisplayComponent from '../../components/maps/MapCalibra import {changeGridDisplay, dropCalibration, offerCurrentGPS, submitCalibratingMap} from '../../redux/actions/map'; import {GPSPoint} from '../../utils/calibration'; import {logToServer} from '../../redux/actions/logs'; -import { useTranslate } from '../../redux/componentHooks'; +import translate from '../../utils/translate'; function mapStateToProps(state: State) { const mapID = state.maps.calibratingMap; const map = state.maps.editedMaps[mapID]; - const translate = useTranslate(); const resultDisplay = (map.calibrationResult) ? `x: ${map.calibrationResult.maxError.x}%, y: ${map.calibrationResult.maxError.y}%` : translate('need.more.points'); diff --git a/src/client/app/redux/actions/conversions.ts b/src/client/app/redux/actions/conversions.ts index 768683d90..782cb48f6 100644 --- a/src/client/app/redux/actions/conversions.ts +++ b/src/client/app/redux/actions/conversions.ts @@ -10,7 +10,7 @@ import { Thunk, Dispatch, GetState } from '../../types/redux/actions'; import { showSuccessNotification, showErrorNotification } from '../../utils/notifications'; -import { useTranslate } from '../../redux/componentHooks'; +import translate from '../../utils/translate'; import * as t from '../../types/redux/conversions'; import { conversionsApi } from '../../utils/api'; import { updateCikAndDBViewsIfNeeded } from './admin'; @@ -58,7 +58,6 @@ export function submitEditedConversion(editedConversion: t.ConversionData, shoul const conversionDataIndex = getState().conversions.submitting.findIndex(conversionData => (( conversionData.sourceId === editedConversion.sourceId) && conversionData.destinationId === editedConversion.destinationId)); - const translate = useTranslate(); // If the editedConversion is not already being submitted if (conversionDataIndex === -1) { @@ -87,7 +86,6 @@ export function submitEditedConversion(editedConversion: t.ConversionData, shoul // Add conversion to database export function addConversion(conversion: t.ConversionData): Dispatch { return async (dispatch: Dispatch) => { - const translate = useTranslate(); try { // Attempt to add conversion to database await conversionsApi.addConversion(conversion); @@ -118,7 +116,6 @@ export function deleteConversion(conversion: t.ConversionData): (dispatch: Dispa // Inform the store we are about to work on this conversion // Update the submitting state array dispatch(conversionsSlice.actions.submitEditedConversion(conversion)); - const translate = useTranslate(); try { // Attempt to delete the conversion from the database await conversionsApi.delete(conversion); diff --git a/src/client/app/redux/actions/map.ts b/src/client/app/redux/actions/map.ts index d58f61f1b..8fb9d33aa 100644 --- a/src/client/app/redux/actions/map.ts +++ b/src/client/app/redux/actions/map.ts @@ -16,7 +16,7 @@ import { import {State} from '../../types/redux/state'; import {mapsApi} from '../../utils/api'; import {showErrorNotification, showSuccessNotification} from '../../utils/notifications'; -import { useTranslate } from '../componentHooks'; +import translate from '../../utils/translate'; import * as moment from 'moment'; import {browserHistory} from '../../utils/history'; import {logToServer} from './logs'; @@ -235,7 +235,6 @@ export function submitNewMap(): Thunk { return async (dispatch: Dispatch, getState: GetState) => { const mapID = getState().maps.calibratingMap; const map = getState().maps.editedMaps[mapID]; - const translate = useTranslate(); try { const acceptableMap: MapData = { ...map, @@ -270,7 +269,6 @@ export function submitEditedMap(mapID: number): Thunk { return async (dispatch: Dispatch, getState: GetState) => { const map = getState().maps.editedMaps[mapID]; dispatch(submitMapEdits(mapID)); - const translate = useTranslate(); try { const acceptableMap: MapData = { ...map, @@ -310,7 +308,6 @@ export function submitEditedMap(mapID: number): Thunk { */ export function removeMap(mapID: number): Thunk { return async (dispatch: Dispatch) => { - const translate = useTranslate(); try { await mapsApi.delete(mapID); dispatch(deleteMap(mapID)); diff --git a/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts b/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts index 022cb053e..2a9b304a0 100644 --- a/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts +++ b/src/client/app/redux/middleware/unauthorizedAccesMiddleware.ts @@ -4,7 +4,7 @@ import { isAsyncThunkAction, isRejected } from '@reduxjs/toolkit'; import { showErrorNotification } from '../../utils/notifications'; -import { useTranslate } from '../componentHooks'; +import translate from '../../utils/translate'; import { AppListener } from '../listenerMiddleware'; import { authApi } from '../api/authApi'; @@ -17,7 +17,6 @@ export const unauthorizedRequestListener = (startListening: AppListener) => { effect: (action: any, { dispatch }): void => { // Look for token failed responses from server const unAuthorizedTokenRequest = (action.payload.status === 401 || action.payload.data?.message === 'Failed to authenticate token.'); - const translate = useTranslate(); if (unAuthorizedTokenRequest) { dispatch(authApi.endpoints.logout.initiate()); showErrorNotification(translate('invalid.token.login')); diff --git a/src/client/app/redux/selectors/adminSelectors.ts b/src/client/app/redux/selectors/adminSelectors.ts index ddc2ceeeb..34422cf68 100644 --- a/src/client/app/redux/selectors/adminSelectors.ts +++ b/src/client/app/redux/selectors/adminSelectors.ts @@ -14,7 +14,7 @@ import { UnitData, UnitType } from '../../types/redux/units'; import { unitsCompatibleWithUnit } from '../../utils/determineCompatibleUnits'; import { AreaUnitType } from '../../utils/getAreaUnitConversion'; import { noUnitTranslated, potentialGraphicUnits } from '../../utils/input'; -import { useTranslate } from '../componentHooks'; +import translate from '../../utils/translate'; import { selectAllUnits, selectUnitDataById } from '../api/unitsApi'; import { selectVisibleMetersAndGroups } from './authVisibilitySelectors'; import { createAppSelector } from './selectors'; @@ -217,7 +217,6 @@ export const selectIsValidConversion = createAppSelector( Cannot mix unit represent TODO Some of these can go away when we make the menus dynamic. */ - const translate = useTranslate(); // The destination cannot be a meter unit. if (destinationId !== -999 && unitDataById[destinationId].typeOfUnit === UnitType.meter) { return [false, translate('conversion.create.destination.meter')]; diff --git a/src/client/app/redux/selectors/lineChartSelectors.ts b/src/client/app/redux/selectors/lineChartSelectors.ts index bdf5e1e6e..d4ca92247 100644 --- a/src/client/app/redux/selectors/lineChartSelectors.ts +++ b/src/client/app/redux/selectors/lineChartSelectors.ts @@ -6,7 +6,7 @@ import * as moment from 'moment'; import { selectShowMinMax } from '../../redux/slices/graphSlice'; import { DataType } from '../../types/Datasources'; import getGraphColor from '../../utils/getGraphColor'; -import { useTranslate } from '../componentHooks'; +import translate from '../../utils/translate'; import { createAppSelector } from './selectors'; import { selectScalingFromEntity, selectNameFromEntity } from './entitySelectors'; import { selectPlotlyMeterDeps, selectPlotlyGroupDeps, selectFromLineReadingsResult } from './plotlyDataSelectors'; @@ -57,7 +57,6 @@ export const selectPlotlyMeterData = selectFromLineReadingsResult( yData.push(readingValue); // All hover have the date, meter name and value. const hoverStart = ` ${timeReading.format('ddd, ll LTS')}
${label}: ${readingValue.toPrecision(6)} ${lineUnitLabel}`; - const translate = useTranslate(); if (showMinMax && reading.max != null) { // We want to show min/max. Note if the data is raw for this meter then all the min/max values are null. // In this case we still push the min/max but plotly will not show them. This is a little extra work diff --git a/src/client/app/redux/thunks/exportThunk.ts b/src/client/app/redux/thunks/exportThunk.ts index 7de8afcc1..06eb6cc75 100644 --- a/src/client/app/redux/thunks/exportThunk.ts +++ b/src/client/app/redux/thunks/exportThunk.ts @@ -20,7 +20,7 @@ import { ConversionData } from '../../types/redux/conversions'; import { ChartTypes, MeterOrGroup } from '../../types/redux/graph'; import graphExport, { downloadRawCSV } from '../../utils/exportData'; import { showErrorNotification } from '../../utils/notifications'; -import { useTranslate } from '../componentHooks'; +import translate from '../../utils/translate'; import { createAppThunk } from './appThunk'; import { selectAnythingFetching } from '../../redux/selectors/apiSelectors'; import { RootState } from '../../store'; @@ -139,7 +139,6 @@ export const exportRawReadings = createAppThunk( const fileSize = (count * 0.082 / 1000); // Decides if the readings should be exported, true if should. let shouldDownload = false; - const translate = useTranslate(); if (fileSize <= adminState.defaultWarningFileSize) { // File sizes that anyone can download without prompting so fine shouldDownload = true; diff --git a/src/client/app/utils/calculateCompare.ts b/src/client/app/utils/calculateCompare.ts index ff9c1b3bb..2c5df83b9 100644 --- a/src/client/app/utils/calculateCompare.ts +++ b/src/client/app/utils/calculateCompare.ts @@ -4,7 +4,7 @@ import { TimeInterval } from '../../../common/TimeInterval'; import * as moment from 'moment'; -import { useTranslate } from '../redux/componentHooks'; +import translate from './translate'; /** * 'Day', 'Week' or 'FourWeeks' @@ -159,7 +159,6 @@ export interface ComparePeriodLabels { * @returns human-readable names for the compare period as {{prev: string, current: string}} */ export function getComparePeriodLabels(comparePeriod: ComparePeriod): ComparePeriodLabels { - const translate = useTranslate(); switch (comparePeriod) { case ComparePeriod.Day: return { prev: translate('yesterday'), current: translate('today') }; @@ -181,7 +180,6 @@ export function getComparePeriodLabels(comparePeriod: ComparePeriod): ComparePer * @returns The label summary */ export function getCompareChangeSummary(change: number, name: string, labels: ComparePeriodLabels): string { - const translate = useTranslate(); if (isNaN(change)) { return `${name} ${translate('has.no.data')}`; } diff --git a/src/client/app/utils/calibration.ts b/src/client/app/utils/calibration.ts index e51fd3f5a..7ec057a4b 100644 --- a/src/client/app/utils/calibration.ts +++ b/src/client/app/utils/calibration.ts @@ -6,7 +6,7 @@ import { showErrorNotification } from './notifications'; import { logToServer } from '../redux/actions/logs'; import { DataType } from '../types/Datasources'; import { MapMetadata } from '../types/redux/map'; -import { useTranslate } from '../redux/componentHooks'; +import translate from './translate'; /** * Defines a Cartesian Point with x & y @@ -120,7 +120,6 @@ export function isValidGPSInput(input: string): boolean { const latitudeConstraint = array[latitudeIndex] >= -90 && array[latitudeIndex] <= 90; const longitudeConstraint = array[longitudeIndex] >= -180 && array[longitudeIndex] <= 180; const result = latitudeConstraint && longitudeConstraint; - const translate = useTranslate(); if (!result) { // TODO It would be nice to return the error and then notify as desired. showErrorNotification(translate('input.gps.range') + input); diff --git a/src/client/app/utils/graphics.ts b/src/client/app/utils/graphics.ts index 5c9eedef4..2a2d45e14 100644 --- a/src/client/app/utils/graphics.ts +++ b/src/client/app/utils/graphics.ts @@ -4,7 +4,7 @@ import { LineGraphRate } from 'types/redux/graph'; import { UnitData, UnitRepresentType } from '../types/redux/units'; -import { useTranslate } from '../redux/componentHooks'; +import translate from './translate'; import { AreaUnitType } from './getAreaUnitConversion'; // Has functions for use with graphics @@ -21,7 +21,6 @@ export function lineUnitLabel(selectUnitState: UnitData, currentSelectedRate: Li selectedAreaUnit: AreaUnitType): { unitLabel: string, needsRateScaling: boolean } { let unitLabel: string = ''; let needsRateScaling = false; - const translate = useTranslate(); // Quantity and flow units have different unit labels. // Look up the type of unit if it is for quantity/flow/raw and decide what to do. // Bar graphics are always quantities. @@ -60,7 +59,6 @@ export function lineUnitLabel(selectUnitState: UnitData, currentSelectedRate: Li * @returns y-axis label */ export function barUnitLabel(selectUnitState: UnitData, areaNormalization: boolean, selectedAreaUnit: AreaUnitType): string { - const translate = useTranslate(); let unitLabel: string = ''; // Quantity and flow units have different unit labels. // Look up the type of unit if it is for quantity/flow (should not be raw) and decide what to do. diff --git a/src/client/app/utils/input.ts b/src/client/app/utils/input.ts index 86c8f610f..d6c67fae4 100644 --- a/src/client/app/utils/input.ts +++ b/src/client/app/utils/input.ts @@ -4,7 +4,7 @@ import { GPSPoint } from './calibration'; import { UnitData, DisplayableType, UnitRepresentType, UnitType, UnitDataById } from '../types/redux/units'; -import { useTranslate } from '../redux/componentHooks'; +import translate from './translate'; import { sortBy } from 'lodash'; /** @@ -89,7 +89,6 @@ export const NoUnit: UnitData = { export function noUnitTranslated(): UnitData { // Untranslated no unit. const unit = NoUnit; - const translate = useTranslate(); // Make the identifier be translated. unit.identifier = translate('unit.none'); return unit; From 77ed7911f853a3e2c83de24ebd46c4e3450d3baa Mon Sep 17 00:00:00 2001 From: Steven Huss-Lederman Date: Mon, 28 Oct 2024 07:54:28 -0500 Subject: [PATCH 4/5] add missing csv menu translations --- src/client/app/translations/data.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/client/app/translations/data.ts b/src/client/app/translations/data.ts index 9c2bed3ca..04be11aa2 100644 --- a/src/client/app/translations/data.ts +++ b/src/client/app/translations/data.ts @@ -592,6 +592,8 @@ const LocaleTranslationData = { "create.unit": "Create a Unit\u{26A1}", "create.user": "Créer un utilisateur", "csv": "CSV", + "csvMeters": "CSV Meters\u{26A1}", + "csvReadings": "CSV Readings\u{26A1}", "csv.file": "Fichier CSV:", "csv.file.error": "Le fichier doit être au format CSV ou GZIP (.csv ou .gz). ", "csv.clear.button": "Forme claire", @@ -1096,6 +1098,8 @@ const LocaleTranslationData = { "create.unit": "Crear una unidad", "create.user": "Crear un usuario", "csv": "CSV", + "csvMeters": "CSV Meters\u{26A1}", + "csvReadings": "CSV Readings\u{26A1}", "csv.file": "Archivo CSV:", "csv.file.error": "El archivo debe estar en formato CSV o GZIP (.csv o .gz). ", "csv.clear.button": "Forma clara", From 773a04fbe3361f869c07c9bd7493b7db1a79468e Mon Sep 17 00:00:00 2001 From: Steven Huss-Lederman Date: Mon, 28 Oct 2024 08:05:46 -0500 Subject: [PATCH 5/5] remove map useTranslate While two functions where in the components directory, they were not in the function component so the React Hooks version of translate should not be used. Before the change it was getting errors and crashing. now it seems fine. --- src/client/app/components/ThreeDComponent.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/app/components/ThreeDComponent.tsx b/src/client/app/components/ThreeDComponent.tsx index 4790be383..b9eac43cf 100644 --- a/src/client/app/components/ThreeDComponent.tsx +++ b/src/client/app/components/ThreeDComponent.tsx @@ -20,7 +20,10 @@ import { UnitDataById } from '../types/redux/units'; import { isValidThreeDInterval, roundTimeIntervalForFetch } from '../utils/dateRangeCompatibility'; import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion'; import { lineUnitLabel } from '../utils/graphics'; +// Both translates are used since some are in the function component where the React Hook is okay +// and some are in other functions where the older method is needed. import { useTranslate } from '../redux/componentHooks'; +import translate from '../utils/translate'; import SpinnerComponent from './SpinnerComponent'; import ThreeDPillComponent from './ThreeDPillComponent'; import Plot from 'react-plotly.js'; @@ -111,7 +114,6 @@ function formatThreeDData( graphState: GraphState, unitDataById: UnitDataById ) { - const translate = useTranslate(); // Initialize Plotly Data const xDataToRender: string[] = []; const yDataToRender: string[] = []; @@ -229,7 +231,6 @@ function setHelpLayout(helpText: string = 'Help Text Goes Here', fontSize: numbe * @returns plotly layout object. */ function setThreeDLayout(zLabelText: string = 'Resource Usage', yDataToRender: string[]) { - const translate = useTranslate(); // Convert date strings to JavaScript Date objects and then get dataRange const dateObjects = yDataToRender.map(dateStr => new Date(dateStr)); const dataMin = Math.min(...dateObjects.map(date => date.getTime()));