Files
firegex-traffic-viewer/frontend/src/components/AddNewService.tsx

141 lines
4.6 KiB
TypeScript
Raw Normal View History

import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch, SegmentedControl, SelectItemProps, Autocomplete, AutocompleteItem } from '@mantine/core';
2022-06-12 12:09:50 +02:00
import { useForm } from '@mantine/hooks';
import React, { useEffect, useState } from 'react';
import { addservice, okNotify, startservice, regex_ipv4, regex_ipv6, getipinterfaces } from '../js/utils';
2022-06-12 12:09:50 +02:00
import { ImCross } from "react-icons/im"
type ServiceAddForm = {
name:string,
port:number,
proto:string,
ip_int:string,
2022-06-30 17:48:04 +02:00
autostart: boolean,
}
interface ItemProps extends AutocompleteItem {
label: string;
}
const AutoCompleteItem = React.forwardRef<HTMLDivElement, ItemProps>(
({ label, value, ...props }: ItemProps, ref) => <div ref={ref} {...props}>
( <b>{label}</b> ) -{">"} <b>{value}</b>
</div>
);
2022-06-15 01:23:54 +02:00
function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) {
2022-06-12 12:09:50 +02:00
const form = useForm({
initialValues: {
name:"",
2022-06-30 15:58:03 +02:00
port:8080,
ip_int:"",
proto:"tcp",
autostart: true
2022-06-12 12:09:50 +02:00
},
validationRules:{
name: (value) => value !== ""?true:false,
2022-06-30 15:58:03 +02:00
port: (value) => value>0 && value<65536,
proto: (value) => ["tcp","udp"].includes(value),
ip_int: (value) => value.match(regex_ipv6)?true:false || value.match(regex_ipv4)?true:false
2022-06-12 12:09:50 +02:00
}
})
const [ipInterfaces, setIpInterfaces] = useState<AutocompleteItem[]>([]);
useEffect(()=>{
getipinterfaces().then(data => {
setIpInterfaces(data.map(item => ({label:item.name, value:item.addr})));
})
},[])
2022-06-15 01:23:54 +02:00
const close = () =>{
onClose()
form.reset()
2022-06-15 08:47:13 +02:00
setError(null)
2022-06-15 01:23:54 +02:00
}
2022-06-12 12:09:50 +02:00
const [submitLoading, setSubmitLoading] = useState(false)
const [error, setError] = useState<string|null>(null)
const submitRequest = ({ name, port, autostart, proto, ip_int }:ServiceAddForm) =>{
2022-06-12 12:09:50 +02:00
setSubmitLoading(true)
addservice({name, port, proto, ip_int }).then( res => {
2022-07-10 15:05:56 +02:00
if (res.status === "ok" && res.service_id){
2022-06-12 12:09:50 +02:00
setSubmitLoading(false)
2022-06-15 01:23:54 +02:00
close();
2022-07-10 15:05:56 +02:00
if (autostart) startservice(res.service_id)
2022-07-07 21:08:02 +02:00
okNotify(`Service ${name} has been added`, `Successfully added service with port ${port}`)
2022-06-12 12:09:50 +02:00
}else{
setSubmitLoading(false)
setError("Invalid request! [ "+res.status+" ]")
2022-06-12 12:09:50 +02:00
}
}).catch( err => {
setSubmitLoading(false)
setError("Request Failed! [ "+err+" ]")
})
}
2022-06-12 12:09:50 +02:00
2022-06-15 01:23:54 +02:00
return <Modal size="xl" title="Add a new service" opened={opened} onClose={close} closeOnClickOutside={false} centered>
<form onSubmit={form.onSubmit(submitRequest)}>
<TextInput
label="Service name"
placeholder="Challenge 01"
{...form.getInputProps('name')}
/>
<Space h="md" />
2022-06-12 12:09:50 +02:00
<Autocomplete
label="Public IP Interface (ipv4/ipv6 + CIDR allowed)"
placeholder="10.1.1.0/24"
itemComponent={AutoCompleteItem}
data={ipInterfaces}
{...form.getInputProps('ip_int')}
/>
<Space h="md" />
2022-06-15 01:23:54 +02:00
<NumberInput
placeholder="8080"
min={1}
max={65535}
2022-06-30 15:58:03 +02:00
label="Public Service port"
2022-06-15 01:23:54 +02:00
{...form.getInputProps('port')}
/>
<Space h="md" />
2022-06-12 12:09:50 +02:00
<div className='center-flex'>
<Switch
label="Auto-Start Service"
{...form.getInputProps('autostart', { type: 'checkbox' })}
/>
<div className="flex-spacer"></div>
<SegmentedControl
data={[
{ label: 'TCP', value: 'tcp' },
{ label: 'UDP', value: 'udp' },
]}
{...form.getInputProps('proto')}
/>
</div>
2022-07-10 15:05:56 +02:00
2022-06-15 01:23:54 +02:00
<Group position="right" mt="md">
<Button loading={submitLoading} type="submit">Add Service</Button>
</Group>
2022-06-12 12:09:50 +02:00
2022-06-15 01:23:54 +02:00
<Space h="md" />
{error?<>
<Notification icon={<ImCross size={14} />} color="red" onClose={()=>{setError(null)}}>
Error: {error}
</Notification><Space h="md" /></>:null}
</form>
</Modal>
2022-06-12 12:09:50 +02:00
}
export default AddNewService;