1
0
mirror of https://github.com/checktheroads/hyperglass synced 2024-05-11 05:55:08 +00:00

252 lines
7.7 KiB
JavaScript
Raw Normal View History

2020-10-07 09:41:58 -07:00
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,
2020-10-07 09:41:58 -07:00
SubmitButton,
} from 'app/components';
import { useConfig } from 'app/context';
2020-01-17 02:50:57 -07:00
format.extend(String.prototype, {});
2020-05-02 16:09:03 -07:00
const formSchema = config =>
yup.object().shape({
query_location: yup
.array()
.of(yup.string())
.required(
config.messages.no_input.format({
2020-10-07 09:41:58 -07:00
field: config.web.text.query_location,
}),
2020-05-02 16:09:03 -07:00
),
query_type: yup
.string()
2020-10-07 09:41:58 -07:00
.required(config.messages.no_input.format({ field: config.web.text.query_type })),
2020-05-02 16:09:03 -07:00
query_vrf: yup.string(),
query_target: yup
.string()
2020-10-07 09:41:58 -07:00
.required(config.messages.no_input.format({ field: config.web.text.query_target })),
2020-05-02 16:09:03 -07:00
});
2020-01-17 02:50:57 -07:00
const FormRow = ({ children, ...props }) => (
2020-05-02 16:09:03 -07:00
<Flex
flexDirection="row"
flexWrap="wrap"
w="100%"
2020-10-07 09:41:58 -07:00
justifyContent={['center', 'center', 'space-between', 'space-between']}
{...props}>
2020-05-02 16:09:03 -07:00
{children}
</Flex>
2020-01-17 02:50:57 -07:00
);
export const HyperglassForm = forwardRef(
2020-10-07 09:41:58 -07:00
({ isSubmitting, setSubmitting, setFormData, greetingAck, setGreetingAck, ...props }, ref) => {
2020-05-02 16:09:03 -07:00
const config = useConfig();
const { handleSubmit, register, unregister, setValue, errors } = useForm({
validationSchema: formSchema(config),
2020-10-07 09:41:58 -07:00
defaultValues: { query_vrf: 'default', query_target: '' },
2020-05-02 16:09:03 -07:00
});
2020-01-27 21:28:27 -07:00
2020-05-02 16:09:03 -07:00
const [queryLocation, setQueryLocation] = useState([]);
2020-10-07 09:41:58 -07:00
const [queryType, setQueryType] = useState('');
const [queryVrf, setQueryVrf] = useState('');
const [queryTarget, setQueryTarget] = useState('');
2020-05-02 16:09:03 -07:00
const [availVrfs, setAvailVrfs] = useState([]);
2020-10-07 09:41:58 -07:00
const [fqdnTarget, setFqdnTarget] = useState('');
const [displayTarget, setDisplayTarget] = useState('');
2020-05-02 16:09:03 -07:00
const [families, setFamilies] = useState([]);
const onSubmit = values => {
if (!greetingAck && config.web.greeting.required) {
window.location.reload(false);
setGreetingAck(false);
} else {
setFormData(values);
setSubmitting(true);
}
};
2020-01-17 02:50:57 -07:00
2020-05-02 16:09:03 -07:00
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,
2020-10-07 09:41:58 -07:00
value: vrf.id,
2020-05-02 16:09:03 -07:00
});
deviceVrfs.push([{ id: vrf.id, ipv4: vrf.ipv4, ipv6: vrf.ipv6 }]);
});
allVrfs.push(locVrfs);
});
const intersecting = intersectionWith(...allVrfs, isEqual);
2020-05-02 16:09:03 -07:00
setAvailVrfs(intersecting);
2020-10-07 09:41:58 -07:00
!intersecting.includes(queryVrf) && queryVrf !== 'default' && setQueryVrf('default');
2020-05-02 16:09:03 -07:00
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))
2020-10-07 09:41:58 -07:00
.filter(v => v.id === 'default')
2020-05-02 16:09:03 -07:00
.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([]);
}
};
2020-01-17 02:50:57 -07:00
2020-05-02 16:09:03 -07:00
const handleChange = e => {
setValue(e.field, e.value);
2020-10-07 09:41:58 -07:00
e.field === 'query_location'
2020-05-02 16:09:03 -07:00
? handleLocChange(e)
2020-10-07 09:41:58 -07:00
: e.field === 'query_type'
2020-05-02 16:09:03 -07:00
? setQueryType(e.value)
2020-10-07 09:41:58 -07:00
: e.field === 'query_vrf'
2020-05-02 16:09:03 -07:00
? setQueryVrf(e.value)
2020-10-07 09:41:58 -07:00
: e.field === 'query_target'
2020-05-02 16:09:03 -07:00
? setQueryTarget(e.value)
: null;
};
2020-01-17 02:50:57 -07:00
2020-05-02 16:09:03 -07:00
const vrfContent = config.content.vrf[queryVrf]?.[queryType];
2020-05-02 16:09:03 -07:00
const validFqdnQueryType =
2020-10-07 09:41:58 -07:00
['ping', 'traceroute', 'bgp_route'].includes(queryType) &&
2020-05-02 16:09:03 -07:00
fqdnTarget &&
2020-10-07 09:41:58 -07:00
queryVrf === 'default'
2020-05-02 16:09:03 -07:00
? fqdnTarget
: null;
2020-01-27 21:28:27 -07:00
2020-05-02 16:09:03 -07:00
useEffect(() => {
2020-10-07 09:41:58 -07:00
register({ name: 'query_location' });
register({ name: 'query_type' });
register({ name: 'query_vrf' });
2020-05-02 16:09:03 -07:00
}, [register]);
Object.keys(errors).length >= 1 && console.error(errors);
return (
<Box
as="form"
onSubmit={handleSubmit(onSubmit)}
2020-10-07 09:41:58 -07:00
maxW={['100%', '100%', '75%', '75%']}
2020-05-02 16:09:03 -07:00
w="100%"
p={0}
mx="auto"
my={4}
textAlign="left"
ref={ref}
2020-10-07 09:41:58 -07:00
{...props}>
<FormRow>
<FormField
label={config.web.text.query_location}
name="query_location"
2020-10-07 09:41:58 -07:00
error={errors.query_location}>
<QueryLocation
onChange={handleChange}
locations={config.networks}
2020-05-02 16:09:03 -07:00
label={config.web.text.query_location}
/>
</FormField>
<FormField
label={config.web.text.query_type}
name="query_type"
error={errors.query_type}
2020-10-07 09:41:58 -07:00
labelAddOn={vrfContent && <HelpModal item={vrfContent} name="query_type" />}>
<QueryType
onChange={handleChange}
queryTypes={config.queries.list}
2020-05-02 16:09:03 -07:00
label={config.web.text.query_type}
/>
</FormField>
</FormRow>
<FormRow>
{availVrfs.length > 1 && (
2020-10-07 09:41:58 -07:00
<FormField label={config.web.text.query_vrf} name="query_vrf" error={errors.query_vrf}>
<QueryVrf
label={config.web.text.query_vrf}
vrfs={availVrfs}
2020-05-02 16:09:03 -07:00
onChange={handleChange}
/>
</FormField>
)}
<FormField
label={config.web.text.query_target}
name="query_target"
error={errors.query_target}
fieldAddOn={
queryLocation.length !== 0 &&
validFqdnQueryType && (
<ResolvedTarget
queryTarget={queryTarget}
fqdnTarget={validFqdnQueryType}
2020-05-02 16:09:03 -07:00
setTarget={handleChange}
families={families}
availVrfs={availVrfs}
2020-05-02 16:09:03 -07:00
/>
)
2020-10-07 09:41:58 -07:00
}>
{queryType === 'bgp_community' && config.queries.bgp_community.mode === 'select' ? (
<CommunitySelect
label={config.queries.bgp_community.display_name}
name="query_target"
register={register}
unregister={unregister}
onChange={handleChange}
communities={config.queries.bgp_community.communities}
/>
) : (
<QueryTarget
name="query_target"
placeholder={config.web.text.query_target}
register={register}
unregister={unregister}
2020-10-07 09:41:58 -07:00
resolveTarget={['ping', 'traceroute', 'bgp_route'].includes(queryType)}
value={queryTarget}
setFqdn={setFqdnTarget}
setTarget={handleChange}
displayValue={displayTarget}
setDisplayValue={setDisplayTarget}
/>
)}
</FormField>
</FormRow>
<FormRow mt={0} justifyContent="flex-end">
<Flex
w="100%"
maxW="100%"
ml="auto"
my={2}
mr={[0, 0, 2, 2]}
flexDirection="column"
2020-10-07 09:41:58 -07:00
flex="0 0 0">
<SubmitButton isLoading={isSubmitting} />
</Flex>
</FormRow>
2020-05-02 16:09:03 -07:00
</Box>
);
2020-10-07 09:41:58 -07:00
},
2020-01-17 02:50:57 -07:00
);