diff --git a/src/components/ToggleSwitch.tsx b/src/components/ToggleSwitch.tsx index de6f2b5c..cda7c65f 100644 --- a/src/components/ToggleSwitch.tsx +++ b/src/components/ToggleSwitch.tsx @@ -1,8 +1,8 @@ -import { ChangeEvent } from 'react' +import { ReactNode, ChangeEvent } from 'react' import styles from './ToggleSwitch.module.css' interface ToggleSwitchProps { - label: string + label: string | ReactNode subtitle?: string onToggle: (isToggled: boolean) => void toggledOn: boolean diff --git a/src/components/settings/FeeConfigModal.tsx b/src/components/settings/FeeConfigModal.tsx index 41b1c009..881ffcda 100644 --- a/src/components/settings/FeeConfigModal.tsx +++ b/src/components/settings/FeeConfigModal.tsx @@ -1,7 +1,7 @@ import { forwardRef, useRef, useCallback, useEffect, useState } from 'react' import * as rb from 'react-bootstrap' import { Trans, useTranslation } from 'react-i18next' -import { Formik, FormikErrors } from 'formik' +import { Formik, FormikErrors, FormikProps } from 'formik' import classNames from 'classnames' import { FEE_CONFIG_KEYS, TxFeeValueUnit, toTxFeeValueUnit, FeeValues, useLoadFeeConfigValues } from '../../hooks/Fees' import { useUpdateConfigValues } from '../../context/ServiceConfigContext' @@ -9,6 +9,10 @@ import { isValidNumber, factorToPercentage, percentageToFactor } from '../../uti import Sprite from '../Sprite' import SegmentedTabs from '../SegmentedTabs' import styles from './FeeConfigModal.module.css' +import { isDebugFeatureEnabled } from '../../constants/debugFeatures' +import ToggleSwitch from '../ToggleSwitch' + +const __dev_allowFeeValuesReset = isDebugFeatureEnabled('allowFeeValuesReset') type SatsPerKiloVByte = number @@ -53,17 +57,21 @@ export type FeeConfigSectionKey = 'tx_fee' | 'cj_fee' const TX_FEE_SECTION_KEY: FeeConfigSectionKey = 'tx_fee' const CJ_FEE_SECTION_KEY: FeeConfigSectionKey = 'cj_fee' +type FeeFormValues = FeeValues & { + enableValidation?: boolean +} + interface FeeConfigFormProps { - initialValues: FeeValues - validate: (values: FeeValues, txFeesUnit: TxFeeValueUnit) => FormikErrors - onSubmit: (values: FeeValues, txFeesUnit: TxFeeValueUnit) => void + initialValues: FeeFormValues + validate: (values: FeeFormValues, txFeesUnit: TxFeeValueUnit) => FormikErrors + onSubmit: (values: FeeFormValues, txFeesUnit: TxFeeValueUnit) => void defaultActiveSectionKey?: FeeConfigSectionKey } const FeeConfigForm = forwardRef( ( { onSubmit, validate, initialValues, defaultActiveSectionKey }: FeeConfigFormProps, - ref: React.Ref, + ref: React.Ref>, ) => { const { t, i18n } = useTranslation() @@ -71,12 +79,34 @@ const FeeConfigForm = forwardRef( return ( validate(values, txFeesUnit)} onSubmit={(values) => onSubmit(values, txFeesUnit)} > {({ handleSubmit, setFieldValue, handleBlur, validateForm, values, touched, errors, isSubmitting }) => ( - + + {__dev_allowFeeValuesReset && ( +
+ + Enable form validation + dev + + } + subtitle={ + 'Ability to reset fee values to test what the UI looks like, when a user does not have these values configured.' + } + toggledOn={values.enableValidation ?? true} + onToggle={(isToggled) => { + setFieldValue('enableValidation', isToggled, true) + }} + disabled={isSubmitting} + /> +
+ )} + @@ -332,9 +362,9 @@ export default function FeeConfigModal({ const [isLoading, setIsLoading] = useState(true) const [isSubmitting, setIsSubmitting] = useState(false) const [loadError, setLoadError] = useState(false) - const [saveErrorMessage, setSaveErrorMessage] = useState(undefined) - const [feeConfigValues, setFeeConfigValues] = useState(null) - const formRef = useRef(null) + const [saveErrorMessage, setSaveErrorMessage] = useState() + const [feeFormValues, setFeeFormValues] = useState(null) + const formRef = useRef>(null) useEffect(() => { setLoadError(false) @@ -347,7 +377,7 @@ export default function FeeConfigModal({ .then((val) => { if (abortCtrl.signal.aborted) return setIsLoading(false) - setFeeConfigValues(val) + setFeeFormValues(val) }) .catch((e) => { if (abortCtrl.signal.aborted) return @@ -415,8 +445,14 @@ export default function FeeConfigModal({ } const validate = useCallback( - (values: FeeValues, txFeesUnit: TxFeeValueUnit) => { - const errors = {} as FormikErrors + (values: FeeFormValues, txFeesUnit: TxFeeValueUnit) => { + const errors = {} as FormikErrors + + if (values.enableValidation === false) { + // do not validate form to enable resetting the values + // this can only be done in dev mode! + return errors + } if ( !isValidNumber(values.tx_fees_factor) || @@ -536,10 +572,10 @@ export default function FeeConfigModal({ ) : ( <> - {feeConfigValues && ( + {feeFormValues && ( {t('settings.fees.text_button_cancel')} + + {__dev_allowFeeValuesReset && ( + { + formRef.current?.setFieldValue('max_cj_fee_abs', '', false) + formRef.current?.setFieldValue('max_cj_fee_rel', '', false) + formRef.current?.setFieldValue('tx_fees', '', false) + formRef.current?.setFieldValue('tx_fees_factor', '', false) + setTimeout(() => formRef.current?.validateForm(), 4) + }} + disabled={isLoading || isSubmitting} + > + Reset form values + + dev + + + )} formRef.current?.requestSubmit()} + onClick={() => formRef.current?.submitForm()} > {isSubmitting ? ( <> diff --git a/src/constants/debugFeatures.ts b/src/constants/debugFeatures.ts index 43f9cfdb..ce284b34 100644 --- a/src/constants/debugFeatures.ts +++ b/src/constants/debugFeatures.ts @@ -6,6 +6,7 @@ interface DebugFeatures { devSetupPage: boolean importDummyMnemonicPhrase: boolean rescanChainPage: boolean + allowFeeValuesReset: boolean fastThemeToggle: boolean } @@ -19,6 +20,7 @@ const debugFeatures: DebugFeatures = { devSetupPage: devMode, importDummyMnemonicPhrase: devMode, rescanChainPage: devMode, + allowFeeValuesReset: devMode, fastThemeToggle: devMode, }