import * as React from 'react'; import { forwardRef, useState, useEffect } from 'react'; import { Box, Flex } from '@chakra-ui/core'; import { useForm } from 'react-hook-form'; import { intersectionWith, isEqual } from 'lodash'; import * as yup from 'yup'; import format from 'string-format'; import { FormField, HelpModal, QueryLocation, QueryType, QueryTarget, CommunitySelect, QueryVrf, ResolvedTarget, SubmitButton, } from 'app/components'; import { useConfig } from 'app/context'; format.extend(String.prototype, {}); const formSchema = config => yup.object().shape({ query_location: yup .array() .of(yup.string()) .required( config.messages.no_input.format({ field: config.web.text.query_location, }), ), query_type: yup .string() .required(config.messages.no_input.format({ field: config.web.text.query_type })), query_vrf: yup.string(), query_target: yup .string() .required(config.messages.no_input.format({ field: config.web.text.query_target })), }); const FormRow = ({ children, ...props }) => ( {children} ); export const HyperglassForm = forwardRef( ({ isSubmitting, setSubmitting, setFormData, greetingAck, setGreetingAck, ...props }, ref) => { const config = useConfig(); const { handleSubmit, register, unregister, setValue, errors } = useForm({ validationSchema: formSchema(config), defaultValues: { query_vrf: 'default', query_target: '' }, }); const [queryLocation, setQueryLocation] = useState([]); const [queryType, setQueryType] = useState(''); const [queryVrf, setQueryVrf] = useState(''); const [queryTarget, setQueryTarget] = useState(''); const [availVrfs, setAvailVrfs] = useState([]); const [fqdnTarget, setFqdnTarget] = useState(''); const [displayTarget, setDisplayTarget] = useState(''); const [families, setFamilies] = useState([]); const onSubmit = values => { if (!greetingAck && config.web.greeting.required) { window.location.reload(false); setGreetingAck(false); } else { setFormData(values); setSubmitting(true); } }; const handleLocChange = locObj => { setQueryLocation(locObj.value); const allVrfs = []; const deviceVrfs = []; locObj.value.map(loc => { const locVrfs = []; config.devices[loc].vrfs.map(vrf => { locVrfs.push({ label: vrf.display_name, value: vrf.id, }); deviceVrfs.push([{ id: vrf.id, ipv4: vrf.ipv4, ipv6: vrf.ipv6 }]); }); allVrfs.push(locVrfs); }); const intersecting = intersectionWith(...allVrfs, isEqual); setAvailVrfs(intersecting); !intersecting.includes(queryVrf) && queryVrf !== 'default' && setQueryVrf('default'); let ipv4 = 0; let ipv6 = 0; deviceVrfs.length !== 0 && intersecting.length !== 0 && deviceVrfs .filter(v => intersecting.every(i => i.id === v.id)) .reduce((a, b) => a.concat(b)) .filter(v => v.id === 'default') .map(v => { v.ipv4 === true && ipv4++; v.ipv6 === true && ipv6++; }); if (ipv4 !== 0 && ipv4 === ipv6) { setFamilies([4, 6]); } else if (ipv4 > ipv6) { setFamilies([4]); } else if (ipv4 < ipv6) { setFamilies([6]); } else { setFamilies([]); } }; const handleChange = e => { setValue(e.field, e.value); e.field === 'query_location' ? handleLocChange(e) : e.field === 'query_type' ? setQueryType(e.value) : e.field === 'query_vrf' ? setQueryVrf(e.value) : e.field === 'query_target' ? setQueryTarget(e.value) : null; }; const vrfContent = config.content.vrf[queryVrf]?.[queryType]; const validFqdnQueryType = ['ping', 'traceroute', 'bgp_route'].includes(queryType) && fqdnTarget && queryVrf === 'default' ? fqdnTarget : null; useEffect(() => { register({ name: 'query_location' }); register({ name: 'query_type' }); register({ name: 'query_vrf' }); }, [register]); Object.keys(errors).length >= 1 && console.error(errors); return ( }> {availVrfs.length > 1 && ( )} ) }> {queryType === 'bgp_community' && config.queries.bgp_community.mode === 'select' ? ( ) : ( )} ); }, );