From 991eb271b2a7e8680c21b4e72f20c0573ae1a030 Mon Sep 17 00:00:00 2001 From: Hin Yan Liew Date: Tue, 26 Nov 2024 15:23:50 -0500 Subject: [PATCH 1/6] Added warnings to admin preferences component --- .../components/admin/PreferencesComponent.tsx | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index ffc2717cb..153da4549 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { cloneDeep, isEqual } from 'lodash'; +import * as moment from 'moment'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import { Button, Input } from 'reactstrap'; @@ -18,7 +19,6 @@ import TimeZoneSelect from '../TimeZoneSelect'; import { defaultAdminState } from '../../redux/slices/adminSlice'; -// TODO: Add warning for invalid data /** * @returns Preferences Component for Administrative use */ @@ -43,6 +43,40 @@ export default function PreferencesComponent() { setLocalAdminPref(cloneDeep(adminPreferences)); }; + // small functions that determine if fields are invalid to warn the user + const invalidReadingFreq = () => { + const frequency = moment.duration(localAdminPref.defaultMeterReadingFrequency); + return !frequency.isValid() || frequency.asSeconds() <= 0; + }; + + // force check some localAdminPref values as numbers, they are stored as strings + const invalidValueLimits = () => { + return Number(localAdminPref.defaultMeterMinimumValue) >= Number(localAdminPref.defaultMeterMaximumValue); + }; + + const invalidDateLimits = () => { + const minMoment = moment(localAdminPref.defaultMeterMinimumDate); + const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); + return !minMoment.isValid() || !maxMoment.isValid() || !minMoment.isBefore(maxMoment); + }; + + const invalidReadingGap = () => { + return Number(localAdminPref.defaultMeterReadingGap) < 0; + }; + + const invalidMeterErrors = () => { + return Number(localAdminPref.defaultMeterMaximumErrors) <= 0; + }; + + const invalidFileSizeLimit = () => { + return Number(localAdminPref.defaultFileSizeLimit) < 0; + }; + + const invalidWarningFileSize = () => { + return Number(localAdminPref.defaultWarningFileSize) < 0 + || Number(localAdminPref.defaultWarningFileSize) > Number(localAdminPref.defaultFileSizeLimit); + }; + return (
makeLocalChanges('defaultMeterReadingFrequency', e.target.value)} + invalid={invalidReadingFreq()} />
@@ -154,6 +189,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMinimumValue} onChange={e => makeLocalChanges('defaultMeterMinimumValue', e.target.value)} maxLength={50} + invalid={invalidValueLimits()} />
@@ -165,6 +201,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMaximumValue} onChange={e => makeLocalChanges('defaultMeterMaximumValue', e.target.value)} maxLength={50} + invalid={invalidValueLimits()} />
@@ -176,6 +213,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMinimumDate} onChange={e => makeLocalChanges('defaultMeterMinimumDate', e.target.value)} placeholder='YYYY-MM-DD HH:MM:SS' + invalid={invalidDateLimits()} />
@@ -187,6 +225,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMaximumDate} onChange={e => makeLocalChanges('defaultMeterMaximumDate', e.target.value)} placeholder='YYYY-MM-DD HH:MM:SS' + invalid={invalidDateLimits()} />
@@ -198,6 +237,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterReadingGap} onChange={e => makeLocalChanges('defaultMeterReadingGap', e.target.value)} maxLength={50} + invalid={invalidReadingGap()} />
@@ -209,6 +249,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMaximumErrors} onChange={e => makeLocalChanges('defaultMeterMaximumErrors', e.target.value)} maxLength={50} + invalid={invalidMeterErrors()} />
@@ -298,6 +339,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultWarningFileSize} onChange={e => makeLocalChanges('defaultWarningFileSize', e.target.value)} maxLength={50} + invalid={invalidWarningFileSize()} />
@@ -309,6 +351,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultFileSizeLimit} onChange={e => makeLocalChanges('defaultFileSizeLimit', e.target.value)} maxLength={50} + invalid={invalidFileSizeLimit()} />
From e517ebbd95d596c11c34c5d7df174c540f65cb95 Mon Sep 17 00:00:00 2001 From: Hin Yan Liew Date: Mon, 2 Dec 2024 17:19:57 -0500 Subject: [PATCH 2/6] Modified invalid data functions and added FormFeedbacks --- .../components/admin/PreferencesComponent.tsx | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index 153da4549..b1d453c27 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -6,9 +6,12 @@ import { cloneDeep, isEqual } from 'lodash'; import * as moment from 'moment'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import { Button, Input } from 'reactstrap'; +import { Button, Input, FormFeedback } from 'reactstrap'; import { UnsavedWarningComponent } from '../UnsavedWarningComponent'; import { preferencesApi } from '../../redux/api/preferencesApi'; +import { + MIN_DATE, MIN_DATE_MOMENT, MAX_DATE, MAX_DATE_MOMENT, MAX_VAL, MIN_VAL, MAX_ERRORS +} from '../../redux/selectors/adminSelectors'; import { PreferenceRequestItem, TrueFalseType } from '../../types/items'; import { ChartTypes } from '../../types/redux/graph'; import { LanguageTypes } from '../../types/redux/i18n'; @@ -50,14 +53,28 @@ export default function PreferencesComponent() { }; // force check some localAdminPref values as numbers, they are stored as strings - const invalidValueLimits = () => { - return Number(localAdminPref.defaultMeterMinimumValue) >= Number(localAdminPref.defaultMeterMaximumValue); + const invalidMinValue = () => { + const min = Number(localAdminPref.defaultMeterMinimumValue); + const max = Number(localAdminPref.defaultMeterMaximumValue); + return min < MIN_VAL || min > max; }; - const invalidDateLimits = () => { + const invalidMaxValue = () => { + const min = Number(localAdminPref.defaultMeterMinimumValue); + const max = Number(localAdminPref.defaultMeterMaximumValue); + return max > MAX_VAL || min > max; + }; + + const invalidMinDate = () => { + const minMoment = moment(localAdminPref.defaultMeterMinimumDate); + const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); + return !minMoment.isValid() || !minMoment.isSameOrAfter(MIN_DATE_MOMENT) || !minMoment.isSameOrBefore(maxMoment); + }; + + const invalidMaxDate = () => { const minMoment = moment(localAdminPref.defaultMeterMinimumDate); const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); - return !minMoment.isValid() || !maxMoment.isValid() || !minMoment.isBefore(maxMoment); + return !maxMoment.isValid() || !maxMoment.isSameOrBefore(MAX_DATE_MOMENT) || !maxMoment.isSameOrAfter(minMoment); }; const invalidReadingGap = () => { @@ -65,7 +82,8 @@ export default function PreferencesComponent() { }; const invalidMeterErrors = () => { - return Number(localAdminPref.defaultMeterMaximumErrors) <= 0; + return Number(localAdminPref.defaultMeterMaximumErrors) < 0 + || Number(localAdminPref.defaultMeterMaximumErrors) > MAX_ERRORS; }; const invalidFileSizeLimit = () => { @@ -189,8 +207,11 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMinimumValue} onChange={e => makeLocalChanges('defaultMeterMinimumValue', e.target.value)} maxLength={50} - invalid={invalidValueLimits()} + invalid={invalidMinValue()} /> + + +

@@ -201,8 +222,11 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMaximumValue} onChange={e => makeLocalChanges('defaultMeterMaximumValue', e.target.value)} maxLength={50} - invalid={invalidValueLimits()} + invalid={invalidMaxValue()} /> + + +

@@ -213,8 +237,11 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMinimumDate} onChange={e => makeLocalChanges('defaultMeterMinimumDate', e.target.value)} placeholder='YYYY-MM-DD HH:MM:SS' - invalid={invalidDateLimits()} + invalid={invalidMinDate()} /> + + +

@@ -225,8 +252,11 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMaximumDate} onChange={e => makeLocalChanges('defaultMeterMaximumDate', e.target.value)} placeholder='YYYY-MM-DD HH:MM:SS' - invalid={invalidDateLimits()} + invalid={invalidMaxDate()} /> + + +

@@ -239,6 +269,9 @@ export default function PreferencesComponent() { maxLength={50} invalid={invalidReadingGap()} /> + + +

@@ -251,6 +284,9 @@ export default function PreferencesComponent() { maxLength={50} invalid={invalidMeterErrors()} /> + + +

@@ -341,6 +377,9 @@ export default function PreferencesComponent() { maxLength={50} invalid={invalidWarningFileSize()} /> + + +

@@ -353,6 +392,9 @@ export default function PreferencesComponent() { maxLength={50} invalid={invalidFileSizeLimit()} /> + + +

From 3eb6d94309d2f50c65bdbde4692afb2c9dd0054b Mon Sep 17 00:00:00 2001 From: Hin Yan Liew Date: Mon, 9 Dec 2024 19:15:40 -0500 Subject: [PATCH 3/6] Fixed small issues with FormFeedback and min/max bounds, added final check to submit button --- .../components/admin/PreferencesComponent.tsx | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index b1d453c27..34f891e41 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -46,7 +46,7 @@ export default function PreferencesComponent() { setLocalAdminPref(cloneDeep(adminPreferences)); }; - // small functions that determine if fields are invalid to warn the user + // small functions that determine if fields are invalid const invalidReadingFreq = () => { const frequency = moment.duration(localAdminPref.defaultMeterReadingFrequency); return !frequency.isValid() || frequency.asSeconds() <= 0; @@ -197,6 +197,9 @@ export default function PreferencesComponent() { onChange={e => makeLocalChanges('defaultMeterReadingFrequency', e.target.value)} invalid={invalidReadingFreq()} /> + + +

@@ -206,6 +209,8 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultMeterMinimumValue} onChange={e => makeLocalChanges('defaultMeterMinimumValue', e.target.value)} + min={MIN_VAL} + max={Number(localAdminPref.defaultMeterMaximumValue)} maxLength={50} invalid={invalidMinValue()} /> @@ -221,6 +226,8 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultMeterMaximumValue} onChange={e => makeLocalChanges('defaultMeterMaximumValue', e.target.value)} + min={Number(localAdminPref.defaultMeterMinimumValue)} + max={MAX_VAL} maxLength={50} invalid={invalidMaxValue()} /> @@ -255,7 +262,7 @@ export default function PreferencesComponent() { invalid={invalidMaxDate()} /> - +

@@ -266,6 +273,7 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultMeterReadingGap} onChange={e => makeLocalChanges('defaultMeterReadingGap', e.target.value)} + min='0' maxLength={50} invalid={invalidReadingGap()} /> @@ -281,6 +289,8 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultMeterMaximumErrors} onChange={e => makeLocalChanges('defaultMeterMaximumErrors', e.target.value)} + min='0' + max={MAX_ERRORS} maxLength={50} invalid={invalidMeterErrors()} /> @@ -374,6 +384,8 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultWarningFileSize} onChange={e => makeLocalChanges('defaultWarningFileSize', e.target.value)} + min='0' + max={Number(localAdminPref.defaultFileSizeLimit)} maxLength={50} invalid={invalidWarningFileSize()} /> @@ -389,6 +401,7 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultFileSizeLimit} onChange={e => makeLocalChanges('defaultFileSizeLimit', e.target.value)} + min='0' maxLength={50} invalid={invalidFileSizeLimit()} /> @@ -427,7 +440,9 @@ export default function PreferencesComponent() { showErrorNotification(translate('failed.to.submit.changes')); }) } - disabled={!hasChanges} + disabled={!hasChanges || invalidReadingFreq() || invalidMinValue() || invalidMaxValue() || invalidMinDate() || invalidMaxDate() + || invalidReadingGap() || invalidMeterErrors() || invalidFileSizeLimit() || invalidWarningFileSize() + } > {translate('submit')} From 11a2adfdf5463766ebfc5c366d6067728f3a154a Mon Sep 17 00:00:00 2001 From: Hin Yan Liew Date: Mon, 9 Dec 2024 21:41:44 -0500 Subject: [PATCH 4/6] added invalid.input key to data.ts and adjusted defaultFileSizeLimit min --- src/client/app/components/admin/PreferencesComponent.tsx | 4 ++-- src/client/app/translations/data.ts | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index 34f891e41..b8d6cfa5e 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -198,7 +198,7 @@ export default function PreferencesComponent() { invalid={invalidReadingFreq()} /> - +
@@ -401,7 +401,7 @@ export default function PreferencesComponent() { type='number' value={localAdminPref.defaultFileSizeLimit} onChange={e => makeLocalChanges('defaultFileSizeLimit', e.target.value)} - min='0' + min={Number(localAdminPref.defaultWarningFileSize)} maxLength={50} invalid={invalidFileSizeLimit()} /> diff --git a/src/client/app/translations/data.ts b/src/client/app/translations/data.ts index 393ffaf5c..fe64e0f3c 100644 --- a/src/client/app/translations/data.ts +++ b/src/client/app/translations/data.ts @@ -277,6 +277,7 @@ const LocaleTranslationData = { "input.gps.coords.second": "in this format -> latitude,longitude", "input.gps.range": "Invalid GPS coordinate, latitude must be an integer between -90 and 90, longitude must be an integer between -180 and 180. You input: ", "insufficient.readings": "Insufficient readings data to process comparison for ", + "invalid.input": "Invalid input", "invalid.number": "Please submit a valid number (between 0 and 2.0)", "invalid.token.login": "Token has expired. Please log in again.", "invalid.token.login.admin": "Token has expired. Please log in again to view this page.", @@ -810,6 +811,7 @@ const LocaleTranslationData = { "input.gps.coords.second": "in this format -> latitude,longitude\u{26A1}", "input.gps.range": "Coordonnée GPS invalide, la latitude doit être un nombre entier entre -90 et 90, la longitude doit être un nombre entier entre -180 et 180. You input: \u{26A1}", "insufficient.readings": "Données de lectures insuffisantes pour la comparaison de processus pour ", + "invalid.input": "Invalid input\u{26A1}", "invalid.number": "Please submit a valid number (between 0 and 2.0)\u{26A1}", "invalid.token.login": "Le jeton a expiré. Connectez-vous à nouveau.", "invalid.token.login.admin": "Le jeton a expiré. Please log in again to view this page.\u{26A1}", @@ -1344,6 +1346,7 @@ const LocaleTranslationData = { "input.gps.coords.second": "de esta forma -> latitud, longitud", "input.gps.range": "Coordenada GPS no válida, la latitud debe ser un número entero entre -90 y 90, la longitud debe ser un número entero entre -180 y 180. Usted puso: ", "insufficient.readings": "Hay insuficientes datos de lecturas para procesar la comparación de ", + "invalid.input": "Invalid input\u{26A1}", "invalid.number": "Por favor indique un número válido (entre 0 a 2.0)", "invalid.token.login": "El token se ha vencido. Inicie la sesión nuevamente", "invalid.token.login.admin": "El token se ha vencido. Inicie la sesión nuevamente para ver esta página.", From 580a3df9972a2fa21caecaf29ff263ff194e3364 Mon Sep 17 00:00:00 2001 From: Hin Yan Liew Date: Tue, 10 Dec 2024 03:29:23 -0500 Subject: [PATCH 5/6] Reformatted invalid data functions --- .../components/admin/PreferencesComponent.tsx | 101 ++++++++---------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index b8d6cfa5e..64016be32 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -46,53 +46,42 @@ export default function PreferencesComponent() { setLocalAdminPref(cloneDeep(adminPreferences)); }; - // small functions that determine if fields are invalid - const invalidReadingFreq = () => { - const frequency = moment.duration(localAdminPref.defaultMeterReadingFrequency); - return !frequency.isValid() || frequency.asSeconds() <= 0; - }; - - // force check some localAdminPref values as numbers, they are stored as strings - const invalidMinValue = () => { - const min = Number(localAdminPref.defaultMeterMinimumValue); - const max = Number(localAdminPref.defaultMeterMaximumValue); - return min < MIN_VAL || min > max; - }; - - const invalidMaxValue = () => { - const min = Number(localAdminPref.defaultMeterMinimumValue); - const max = Number(localAdminPref.defaultMeterMaximumValue); - return max > MAX_VAL || min > max; - }; - - const invalidMinDate = () => { - const minMoment = moment(localAdminPref.defaultMeterMinimumDate); - const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); - return !minMoment.isValid() || !minMoment.isSameOrAfter(MIN_DATE_MOMENT) || !minMoment.isSameOrBefore(maxMoment); - }; + // Functions for input validation and warnings. Each returns true if the user inputs invalid data into its field + // Need to be functions due to static reference. If they were booleans they wouldn't update when localAdminPref updates + const invalidFuncs = { + readingFreq: (): boolean => { + const frequency = moment.duration(localAdminPref.defaultMeterReadingFrequency); + return !frequency.isValid() || frequency.asSeconds() <= 0; + }, + minValue: (): boolean => { + const min = Number(localAdminPref.defaultMeterMinimumValue); + const max = Number(localAdminPref.defaultMeterMaximumValue); + return min < MIN_VAL || min > max; + }, + maxValue: (): boolean => { + const min = Number(localAdminPref.defaultMeterMinimumValue); + const max = Number(localAdminPref.defaultMeterMaximumValue); + return max > MAX_VAL || min > max; + }, + minDate: (): boolean => { + const minMoment = moment(localAdminPref.defaultMeterMinimumDate); + const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); + return !minMoment.isValid() || !minMoment.isSameOrAfter(MIN_DATE_MOMENT) || !minMoment.isSameOrBefore(maxMoment); + }, + maxDate: (): boolean => { + const minMoment = moment(localAdminPref.defaultMeterMinimumDate); + const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); + return !maxMoment.isValid() || !maxMoment.isSameOrBefore(MAX_DATE_MOMENT) || !maxMoment.isSameOrAfter(minMoment); + }, + readingGap: (): boolean => Number(localAdminPref.defaultMeterReadingGap) < 0, - const invalidMaxDate = () => { - const minMoment = moment(localAdminPref.defaultMeterMinimumDate); - const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); - return !maxMoment.isValid() || !maxMoment.isSameOrBefore(MAX_DATE_MOMENT) || !maxMoment.isSameOrAfter(minMoment); - }; - - const invalidReadingGap = () => { - return Number(localAdminPref.defaultMeterReadingGap) < 0; - }; + meterErrors: (): boolean => Number(localAdminPref.defaultMeterMaximumErrors) < 0 + || Number(localAdminPref.defaultMeterMaximumErrors) > MAX_ERRORS, - const invalidMeterErrors = () => { - return Number(localAdminPref.defaultMeterMaximumErrors) < 0 - || Number(localAdminPref.defaultMeterMaximumErrors) > MAX_ERRORS; - }; + fileSizeLimit: (): boolean => Number(localAdminPref.defaultFileSizeLimit) < 0, - const invalidFileSizeLimit = () => { - return Number(localAdminPref.defaultFileSizeLimit) < 0; - }; - - const invalidWarningFileSize = () => { - return Number(localAdminPref.defaultWarningFileSize) < 0 - || Number(localAdminPref.defaultWarningFileSize) > Number(localAdminPref.defaultFileSizeLimit); + warningFileSize: (): boolean => Number(localAdminPref.defaultWarningFileSize) < 0 + || Number(localAdminPref.defaultWarningFileSize) > Number(localAdminPref.defaultFileSizeLimit) }; return ( @@ -195,7 +184,7 @@ export default function PreferencesComponent() { type='text' value={localAdminPref.defaultMeterReadingFrequency} onChange={e => makeLocalChanges('defaultMeterReadingFrequency', e.target.value)} - invalid={invalidReadingFreq()} + invalid={invalidFuncs.readingFreq()} /> @@ -212,7 +201,7 @@ export default function PreferencesComponent() { min={MIN_VAL} max={Number(localAdminPref.defaultMeterMaximumValue)} maxLength={50} - invalid={invalidMinValue()} + invalid={invalidFuncs.minValue()} /> @@ -229,7 +218,7 @@ export default function PreferencesComponent() { min={Number(localAdminPref.defaultMeterMinimumValue)} max={MAX_VAL} maxLength={50} - invalid={invalidMaxValue()} + invalid={invalidFuncs.maxValue()} /> @@ -244,7 +233,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMinimumDate} onChange={e => makeLocalChanges('defaultMeterMinimumDate', e.target.value)} placeholder='YYYY-MM-DD HH:MM:SS' - invalid={invalidMinDate()} + invalid={invalidFuncs.minDate()} /> @@ -259,7 +248,7 @@ export default function PreferencesComponent() { value={localAdminPref.defaultMeterMaximumDate} onChange={e => makeLocalChanges('defaultMeterMaximumDate', e.target.value)} placeholder='YYYY-MM-DD HH:MM:SS' - invalid={invalidMaxDate()} + invalid={invalidFuncs.maxDate()} /> @@ -275,7 +264,7 @@ export default function PreferencesComponent() { onChange={e => makeLocalChanges('defaultMeterReadingGap', e.target.value)} min='0' maxLength={50} - invalid={invalidReadingGap()} + invalid={invalidFuncs.readingGap()} /> @@ -292,7 +281,7 @@ export default function PreferencesComponent() { min='0' max={MAX_ERRORS} maxLength={50} - invalid={invalidMeterErrors()} + invalid={invalidFuncs.meterErrors()} /> @@ -387,7 +376,7 @@ export default function PreferencesComponent() { min='0' max={Number(localAdminPref.defaultFileSizeLimit)} maxLength={50} - invalid={invalidWarningFileSize()} + invalid={invalidFuncs.warningFileSize()} /> @@ -403,7 +392,7 @@ export default function PreferencesComponent() { onChange={e => makeLocalChanges('defaultFileSizeLimit', e.target.value)} min={Number(localAdminPref.defaultWarningFileSize)} maxLength={50} - invalid={invalidFileSizeLimit()} + invalid={invalidFuncs.fileSizeLimit()} /> @@ -425,6 +414,7 @@ export default function PreferencesComponent() { onClick={discardChanges} disabled={!hasChanges} style={{ marginRight: '20px' }} + color='secondary' > {translate('discard.changes')} @@ -440,9 +430,8 @@ export default function PreferencesComponent() { showErrorNotification(translate('failed.to.submit.changes')); }) } - disabled={!hasChanges || invalidReadingFreq() || invalidMinValue() || invalidMaxValue() || invalidMinDate() || invalidMaxDate() - || invalidReadingGap() || invalidMeterErrors() || invalidFileSizeLimit() || invalidWarningFileSize() - } + disabled={!hasChanges || Object.values(invalidFuncs).some(check => check())} + color='primary' > {translate('submit')} From 3f768e66b2cc7ec0e9c9c06779c5198f665535c0 Mon Sep 17 00:00:00 2001 From: Steven Huss-Lederman Date: Tue, 10 Dec 2024 09:09:12 -0600 Subject: [PATCH 6/6] minor fixes - Put braces around implicit functions as preferred by OED. - Reorder two functions so same as shown to user. - Add file size limit to check functions and form feedback. - Minor formatting. --- .../components/admin/PreferencesComponent.tsx | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/client/app/components/admin/PreferencesComponent.tsx b/src/client/app/components/admin/PreferencesComponent.tsx index 64016be32..265244c48 100644 --- a/src/client/app/components/admin/PreferencesComponent.tsx +++ b/src/client/app/components/admin/PreferencesComponent.tsx @@ -56,7 +56,7 @@ export default function PreferencesComponent() { minValue: (): boolean => { const min = Number(localAdminPref.defaultMeterMinimumValue); const max = Number(localAdminPref.defaultMeterMaximumValue); - return min < MIN_VAL || min > max; + return min < MIN_VAL || min > max; }, maxValue: (): boolean => { const min = Number(localAdminPref.defaultMeterMinimumValue); @@ -73,15 +73,22 @@ export default function PreferencesComponent() { const maxMoment = moment(localAdminPref.defaultMeterMaximumDate); return !maxMoment.isValid() || !maxMoment.isSameOrBefore(MAX_DATE_MOMENT) || !maxMoment.isSameOrAfter(minMoment); }, - readingGap: (): boolean => Number(localAdminPref.defaultMeterReadingGap) < 0, + readingGap: (): boolean => { return Number(localAdminPref.defaultMeterReadingGap) < 0; }, - meterErrors: (): boolean => Number(localAdminPref.defaultMeterMaximumErrors) < 0 - || Number(localAdminPref.defaultMeterMaximumErrors) > MAX_ERRORS, + meterErrors: (): boolean => { + return Number(localAdminPref.defaultMeterMaximumErrors) < 0 + || Number(localAdminPref.defaultMeterMaximumErrors) > MAX_ERRORS; + }, - fileSizeLimit: (): boolean => Number(localAdminPref.defaultFileSizeLimit) < 0, + warningFileSize: (): boolean => { + return Number(localAdminPref.defaultWarningFileSize) < 0 + || Number(localAdminPref.defaultWarningFileSize) > Number(localAdminPref.defaultFileSizeLimit); + }, - warningFileSize: (): boolean => Number(localAdminPref.defaultWarningFileSize) < 0 - || Number(localAdminPref.defaultWarningFileSize) > Number(localAdminPref.defaultFileSizeLimit) + fileSizeLimit: (): boolean => { + return Number(localAdminPref.defaultFileSizeLimit) < 0 + || Number(localAdminPref.defaultWarningFileSize) > Number(localAdminPref.defaultFileSizeLimit); + } }; return ( @@ -204,7 +211,7 @@ export default function PreferencesComponent() { invalid={invalidFuncs.minValue()} /> - +
@@ -221,7 +228,7 @@ export default function PreferencesComponent() { invalid={invalidFuncs.maxValue()} /> - +
@@ -267,7 +274,7 @@ export default function PreferencesComponent() { invalid={invalidFuncs.readingGap()} /> - +
@@ -284,7 +291,7 @@ export default function PreferencesComponent() { invalid={invalidFuncs.meterErrors()} /> - +
@@ -379,7 +386,7 @@ export default function PreferencesComponent() { invalid={invalidFuncs.warningFileSize()} /> - +
@@ -395,7 +402,7 @@ export default function PreferencesComponent() { invalid={invalidFuncs.fileSizeLimit()} /> - +