import React, { useEffect, useCallback } from 'react'; import { useForm, Controller } from 'react-hook-form'; import { Trans, useTranslation } from 'react-i18next'; import i18n from 'i18next'; import Controls from './Controls'; import AddressList from './AddressList'; import { getInterfaceIp } from '../../helpers/helpers'; import { ALL_INTERFACES_IP, ADDRESS_IN_USE_TEXT, PORT_53_FAQ_LINK, STATUS_RESPONSE, STANDARD_DNS_PORT, STANDARD_WEB_PORT, MAX_PORT, MIN_PORT, } from '../../helpers/constants'; import { validateRequiredValue } from '../../helpers/validators'; import { InstallInterface } from '../../initialState'; import { Input } from '../../components/ui/Controls/Input'; import { Select } from '../../components/ui/Controls/Select'; import { toNumber } from '../../helpers/form'; const validateInstallPort = (value: number) => { if (value < MIN_PORT || value > MAX_PORT) { return i18n.t('form_error_port'); } return undefined; }; export type WebConfig = { ip: string; port: number; }; export type DnsConfig = { ip: string; port: number; }; export type SettingsFormValues = { web: WebConfig; dns: DnsConfig; }; type StaticIpType = { ip: string; static: string; }; export type ConfigType = { web: { ip: string; port?: number; status: string; can_autofix: boolean; }; dns: { ip: string; port?: number; status: string; can_autofix: boolean; }; staticIp: StaticIpType; }; type Props = { handleSubmit: (data: SettingsFormValues) => void; handleChange?: (data: SettingsFormValues) => unknown; handleFix: (web: WebConfig, dns: DnsConfig, set_static_ip: boolean) => void; validateForm: (data: SettingsFormValues) => void; config: ConfigType; interfaces: InstallInterface[]; initialValues?: object; }; const renderInterfaces = (interfaces: InstallInterface[]) => Object.values(interfaces).map((option: InstallInterface) => { const { name, ip_addresses, flags } = option; if (option && ip_addresses?.length > 0) { const ip = getInterfaceIp(option); const isUp = flags?.includes('up'); return ( ); } return null; }); export const Settings = ({ handleSubmit, handleFix, validateForm, config, interfaces }: Props) => { const { t } = useTranslation(); const defaultValues = { web: { ip: config.web.ip || ALL_INTERFACES_IP, port: config.web.port || STANDARD_WEB_PORT, }, dns: { ip: config.dns.ip || ALL_INTERFACES_IP, port: config.dns.port || STANDARD_DNS_PORT, }, }; const { control, watch, handleSubmit: reactHookFormSubmit, formState: { isValid }, } = useForm({ defaultValues, mode: 'onBlur', }); const watchFields = watch(); const { status: webStatus, can_autofix: isWebFixAvailable } = config.web; const { status: dnsStatus, can_autofix: isDnsFixAvailable } = config.dns; const { staticIp } = config; const webIpVal = watch('web.ip'); const webPortVal = watch('web.port'); const dnsIpVal = watch('dns.ip'); const dnsPortVal = watch('dns.port'); useEffect(() => { const webPortError = validateInstallPort(webPortVal); const dnsPortError = validateInstallPort(dnsPortVal); if (!isValid || webPortError || dnsPortError) { return; } validateForm({ web: { ip: webIpVal, port: webPortVal, }, dns: { ip: dnsIpVal, port: dnsPortVal, }, }); }, [webIpVal, webPortVal, dnsIpVal, dnsPortVal]); const handleAutofix = (type: string) => { const web = { ip: watchFields.web?.ip, port: watchFields.web?.port, autofix: false, }; const dns = { ip: watchFields.dns?.ip, port: watchFields.dns?.port, autofix: false, }; const set_static_ip = false; if (type === 'web') { web.autofix = true; } else { dns.autofix = true; } handleFix(web, dns, set_static_ip); }; const handleStaticIp = (ip: string) => { const web = { ip: watchFields.web?.ip, port: watchFields.web?.port, autofix: false, }; const dns = { ip: watchFields.dns?.ip, port: watchFields.dns?.port, autofix: false, }; const set_static_ip = true; if (window.confirm(t('confirm_static_ip', { ip }))) { handleFix(web, dns, set_static_ip); } }; const getStaticIpMessage = useCallback( (staticIp: StaticIpType) => { const { static: status, ip } = staticIp; switch (status) { case STATUS_RESPONSE.NO: return ( <>
text]}> install_static_configure
); case STATUS_RESPONSE.ERROR: return (
install_static_error
); case STATUS_RESPONSE.YES: return (
install_static_ok
); default: return null; } }, [handleStaticIp], ); const onSubmit = (data: any) => { validateForm(data); handleSubmit(data); }; return (
install_settings_title
( )} />
( { const { value } = e.target; field.onChange(toNumber(value)); }} /> )} />
{webStatus && (
{webStatus} {isWebFixAvailable && ( )}
)}
install_settings_interface_link
install_settings_dns
( )} />
( { const { value } = e.target; field.onChange(toNumber(value)); }} /> )} />
{dnsStatus && ( <>
{dnsStatus} {isDnsFixAvailable && ( )}
{isDnsFixAvailable && (

autofix_warning_text

text]}>autofix_warning_list

autofix_warning_result

)} )} {watchFields.dns?.port === STANDARD_DNS_PORT && !isDnsFixAvailable && dnsStatus?.includes(ADDRESS_IN_USE_TEXT) && ( link , ]}> port_53_faq_link )}
install_settings_dns_desc
static_ip
static_ip_desc
{getStaticIpMessage(staticIp)}
); };