Improve stability and functionalities
This commit is contained in:
@@ -15,12 +15,15 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
name:"",
|
||||
port:1,
|
||||
port:8080,
|
||||
internalPort:30001,
|
||||
chosenInternalPort:false,
|
||||
autostart: true
|
||||
},
|
||||
validationRules:{
|
||||
name: (value) => value !== ""?true:false,
|
||||
port: (value) => value>0 && value<65536
|
||||
port: (value) => value>0 && value<65536,
|
||||
internalPort: (value) => value>0 && value<65536,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -66,15 +69,34 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
|
||||
placeholder="8080"
|
||||
min={1}
|
||||
max={65535}
|
||||
label="Service port"
|
||||
label="Public Service port"
|
||||
{...form.getInputProps('port')}
|
||||
/>
|
||||
|
||||
{form.values.chosenInternalPort?<>
|
||||
<Space h="md" />
|
||||
<NumberInput
|
||||
placeholder="8080"
|
||||
min={1}
|
||||
max={65535}
|
||||
label="Internal Proxy Port"
|
||||
{...form.getInputProps('internalPort')}
|
||||
/>
|
||||
<Space h="sm" />
|
||||
</>:null}
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Switch
|
||||
label="Auto-Start Service"
|
||||
{...form.getInputProps('autostart', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Space h="md" />
|
||||
|
||||
<Switch
|
||||
label="Auto-Start Service"
|
||||
{...form.getInputProps('autostart', { type: 'checkbox' })}
|
||||
label="Choose internal port"
|
||||
{...form.getInputProps('chosenInternalPort', { type: 'checkbox' })}
|
||||
/>
|
||||
|
||||
<Group position="right" mt="md">
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Grid, Text, Title, Badge, Space, ActionIcon, Tooltip } from '@mantine/core';
|
||||
import React, { useState } from 'react';
|
||||
import { RegexFilter } from '../../js/models';
|
||||
import { deleteregex, errorNotify, fireUpdateRequest, getHumanReadableRegex, okNotify } from '../../js/utils';
|
||||
import { activateregex, deactivateregex, deleteregex, errorNotify, fireUpdateRequest, getHumanReadableRegex, okNotify } from '../../js/utils';
|
||||
import style from "./RegexView.module.scss";
|
||||
import { BsTrashFill } from "react-icons/bs"
|
||||
import YesNoModal from '../YesNoModal';
|
||||
import FilterTypeSelector from '../FilterTypeSelector';
|
||||
import { FaPause, FaPlay } from 'react-icons/fa';
|
||||
|
||||
|
||||
function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
@@ -17,7 +18,8 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
let regex_expr = getHumanReadableRegex(regexInfo.regex);
|
||||
|
||||
const [deleteModal, setDeleteModal] = useState(false);
|
||||
const [tooltipOpened, setTooltipOpened] = useState(false);
|
||||
const [deleteTooltipOpened, setDeleteTooltipOpened] = useState(false);
|
||||
const [statusTooltipOpened, setStatusTooltipOpened] = useState(false);
|
||||
|
||||
const deleteRegex = () => {
|
||||
deleteregex(regexInfo.id).then(res => {
|
||||
@@ -30,6 +32,19 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
}).catch( err => errorNotify(`Regex ${regex_expr} deleation failed!`,`Error: ${err}`))
|
||||
}
|
||||
|
||||
const changeRegexStatus = () => {
|
||||
|
||||
(regexInfo.active?deactivateregex:activateregex)(regexInfo.id).then(res => {
|
||||
if(!res){
|
||||
okNotify(`Regex ${regex_expr} ${regexInfo.active?"deactivated":"activated"} successfully!`,`Regex '${regex_expr}' ID:${regexInfo.id} has been ${regexInfo.active?"deactivated":"activated"}!`)
|
||||
fireUpdateRequest()
|
||||
}else{
|
||||
errorNotify(`Regex ${regex_expr} ${regexInfo.active?"deactivation":"activation"} failed!`,`Error: ${res}`)
|
||||
}
|
||||
}).catch( err => errorNotify(`Regex ${regex_expr} ${regexInfo.active?"deactivation":"activation"} failed!`,`Error: ${err}`))
|
||||
|
||||
}
|
||||
|
||||
return <div className={style.box}>
|
||||
<Grid>
|
||||
<Grid.Col span={2}>
|
||||
@@ -38,14 +53,22 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
<Grid.Col span={8}>
|
||||
<Text className={style.regex_text}> {regex_expr}</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Tooltip label="Delete regex" zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color="red" opened={tooltipOpened} tooltipId="tooltip-id">
|
||||
<Grid.Col span={2} className='center-flex'>
|
||||
<Space w="xs" />
|
||||
<Tooltip label={regexInfo.active?"Deactivate":"Activate"} zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color={regexInfo.active?"orange":"teal"} opened={statusTooltipOpened}>
|
||||
<ActionIcon color={regexInfo.active?"orange":"teal"} onClick={changeRegexStatus} size="xl" radius="md" variant="filled"
|
||||
onFocus={() => setStatusTooltipOpened(false)} onBlur={() => setStatusTooltipOpened(false)}
|
||||
onMouseEnter={() => setStatusTooltipOpened(true)} onMouseLeave={() => setStatusTooltipOpened(false)}
|
||||
>{regexInfo.active?<FaPause size="20px" />:<FaPlay size="20px" />}</ActionIcon>
|
||||
</Tooltip>
|
||||
<Space w="xs" />
|
||||
<Tooltip label="Delete regex" zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color="red" opened={deleteTooltipOpened} >
|
||||
<ActionIcon color="red" onClick={()=>setDeleteModal(true)} size="xl" radius="md" variant="filled"
|
||||
aria-describedby="tooltip-id"
|
||||
onFocus={() => setTooltipOpened(false)} onBlur={() => setTooltipOpened(false)}
|
||||
onMouseEnter={() => setTooltipOpened(true)} onMouseLeave={() => setTooltipOpened(false)}
|
||||
onFocus={() => setDeleteTooltipOpened(false)} onBlur={() => setDeleteTooltipOpened(false)}
|
||||
onMouseEnter={() => setDeleteTooltipOpened(true)} onMouseLeave={() => setDeleteTooltipOpened(false)}
|
||||
><BsTrashFill size={22} /></ActionIcon>
|
||||
</Tooltip>
|
||||
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2} />
|
||||
<Grid.Col className='center-flex-row' span={4}>
|
||||
@@ -58,9 +81,12 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
/>
|
||||
<Space h="md" />
|
||||
<div className='center-flex'>
|
||||
<Badge size="md" color="green" variant="filled">Service: {regexInfo.service_id}</Badge>
|
||||
<Badge size="md" color="cyan" variant="filled">Service: {regexInfo.service_id}</Badge>
|
||||
<Space w="xs" />
|
||||
<Badge size="md" color={regexInfo.active?"lime":"red"} variant="filled">{regexInfo.active?"ACTIVE":"DISABLED"}</Badge>
|
||||
<Space w="xs" />
|
||||
<Badge size="md" color="gray" variant="filled">ID: {regexInfo.id}</Badge>
|
||||
|
||||
</div>
|
||||
</Grid.Col>
|
||||
<Grid.Col style={{width:"100%"}} span={6}>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { ActionIcon, Badge, Grid, MediaQuery, Space, Title, Tooltip } from '@mantine/core';
|
||||
import { ActionIcon, Badge, Divider, Grid, MediaQuery, Menu, Space, Title, Tooltip } from '@mantine/core';
|
||||
import React, { useState } from 'react';
|
||||
import { FaPause, FaPlay, FaStop } from 'react-icons/fa';
|
||||
import { Service } from '../../js/models';
|
||||
import { MdOutlineArrowForwardIos } from "react-icons/md"
|
||||
import style from "./ServiceRow.module.scss";
|
||||
import YesNoModal from '../YesNoModal';
|
||||
import { errorNotify, fireUpdateRequest, okNotify, pauseservice, startservice, stopservice } from '../../js/utils';
|
||||
import { deleteservice, errorNotify, fireUpdateRequest, okNotify, pauseservice, regenport, startservice, stopservice } from '../../js/utils';
|
||||
import { BsArrowRepeat, BsTrashFill } from 'react-icons/bs';
|
||||
import { TbNumbers } from 'react-icons/tb';
|
||||
import { BiRename } from 'react-icons/bi'
|
||||
|
||||
//"status":"stop"/"wait"/"active"/"pause",
|
||||
function ServiceRow({ service, onClick, additional_buttons }:{ service:Service, onClick?:()=>void, additional_buttons?:any }) {
|
||||
function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) {
|
||||
|
||||
let status_color = "gray";
|
||||
switch(service.status){
|
||||
@@ -21,6 +24,8 @@ function ServiceRow({ service, onClick, additional_buttons }:{ service:Service,
|
||||
const [stopModal, setStopModal] = useState(false);
|
||||
const [buttonLoading, setButtonLoading] = useState(false)
|
||||
const [tooltipStopOpened, setTooltipStopOpened] = useState(false);
|
||||
const [deleteModal, setDeleteModal] = useState(false)
|
||||
const [changePortModal, setChangePortModal] = useState(false)
|
||||
|
||||
const stopService = async () => {
|
||||
setButtonLoading(true)
|
||||
@@ -68,6 +73,31 @@ function ServiceRow({ service, onClick, additional_buttons }:{ service:Service,
|
||||
|
||||
}
|
||||
|
||||
const deleteService = () => {
|
||||
deleteservice(service.id).then(res => {
|
||||
if (!res){
|
||||
okNotify("Service delete complete!",`The service ${service.id} has been deleted!`)
|
||||
fireUpdateRequest();
|
||||
}else
|
||||
errorNotify("An error occurred while deleting a service",`Error: ${res}`)
|
||||
}).catch(err => {
|
||||
errorNotify("An error occurred while deleting a service",`Error: ${err}`)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const changePort = () => {
|
||||
regenport(service.id).then(res => {
|
||||
if (!res){
|
||||
okNotify("Service port regeneration completed!",`The service ${service.id} has changed the internal port!`)
|
||||
fireUpdateRequest();
|
||||
}else
|
||||
errorNotify("An error occurred while changing the internal service port",`Error: ${res}`)
|
||||
}).catch(err => {
|
||||
errorNotify("An error occurred while changing the internal service port",`Error: ${err}`)
|
||||
})
|
||||
}
|
||||
|
||||
return <>
|
||||
<Grid className={style.row} justify="flex-end" style={{width:"100%"}}>
|
||||
<Grid.Col md={4} xs={12}>
|
||||
@@ -110,7 +140,21 @@ function ServiceRow({ service, onClick, additional_buttons }:{ service:Service,
|
||||
<><Space w="xl" /><Space w="xl" /></>
|
||||
</MediaQuery>
|
||||
<div className="center-flex">
|
||||
{additional_buttons}
|
||||
<Menu>
|
||||
<Menu.Label><b>Rename service</b></Menu.Label>
|
||||
<Menu.Item icon={<BiRename size={18} />} onClick={()=>{}}>Change service name</Menu.Item>
|
||||
<Divider />
|
||||
<Menu.Label><b>Public proxy port</b></Menu.Label>
|
||||
<Menu.Item icon={<TbNumbers size={18} />} onClick={()=>{}}>Change port</Menu.Item>
|
||||
<Divider />
|
||||
<Menu.Label><b>Internal proxy port</b></Menu.Label>
|
||||
<Menu.Item icon={<BsArrowRepeat size={18} />} onClick={()=>setChangePortModal(true)}>Regen port</Menu.Item>
|
||||
<Menu.Item icon={<TbNumbers size={18} />} onClick={()=>{}}>Choose port</Menu.Item>
|
||||
<Divider />
|
||||
<Menu.Label><b>Delete service</b></Menu.Label>
|
||||
<Menu.Item color="red" icon={<BsTrashFill size={18} />} onClick={()=>setDeleteModal(true)}>Delete Service</Menu.Item>
|
||||
</Menu>
|
||||
<Space w="md"/>
|
||||
{["pause","wait"].includes(service.status)?
|
||||
|
||||
<Tooltip label="Stop service" zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color="orange" opened={tooltipStopOpened} tooltipId="tooltip-stop-id">
|
||||
@@ -159,6 +203,20 @@ function ServiceRow({ service, onClick, additional_buttons }:{ service:Service,
|
||||
opened={stopModal}
|
||||
/>
|
||||
<hr style={{width:"100%"}}/>
|
||||
<YesNoModal
|
||||
title='Are you sure to delete this service?'
|
||||
description={`You are going to delete the service '${service.id}', causing the stopping of the firewall and deleting all the regex associated. This will cause the shutdown of your service! ⚠️`}
|
||||
onClose={()=>setDeleteModal(false) }
|
||||
action={deleteService}
|
||||
opened={deleteModal}
|
||||
/>
|
||||
<YesNoModal
|
||||
title='Are you sure to change the proxy internal port?'
|
||||
description={`You are going to change the proxy port '${service.internal_port}'. This will cause the shutdown of your service temporarily! ⚠️`}
|
||||
onClose={()=>setChangePortModal(false)}
|
||||
action={changePort}
|
||||
opened={changePortModal}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ export type RegexFilter = {
|
||||
is_blacklist:boolean,
|
||||
is_case_sensitive:boolean,
|
||||
mode:string //C S B => C->S S->C BOTH
|
||||
n_packets:number
|
||||
n_packets:number,
|
||||
active:boolean
|
||||
}
|
||||
|
||||
export type RegexAddForm = {
|
||||
|
||||
@@ -99,6 +99,16 @@ export async function deleteregex(regex_id:number){
|
||||
return status === "ok"?undefined:status
|
||||
}
|
||||
|
||||
export async function activateregex(regex_id:number){
|
||||
const { status } = await getapi(`regex/${regex_id}/enable`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
}
|
||||
|
||||
export async function deactivateregex(regex_id:number){
|
||||
const { status } = await getapi(`regex/${regex_id}/disable`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
}
|
||||
|
||||
export async function startservice(service_id:string){
|
||||
const { status } = await getapi(`service/${service_id}/start`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
@@ -127,6 +137,7 @@ export async function deleteservice(service_id:string) {
|
||||
return status === "ok"?undefined:status
|
||||
}
|
||||
|
||||
|
||||
export async function addregex(data:RegexAddForm) {
|
||||
const { status } = await postapi("regexes/add",data) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { ActionIcon, Grid, LoadingOverlay, Space, Title, Tooltip } from '@mantine/core';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { BsTrashFill } from 'react-icons/bs';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import RegexView from '../components/RegexView';
|
||||
import ServiceRow from '../components/ServiceRow';
|
||||
import AddNewRegex from '../components/AddNewRegex';
|
||||
import { BsPlusLg } from "react-icons/bs";
|
||||
import YesNoModal from '../components/YesNoModal';
|
||||
import { RegexFilter, Service } from '../js/models';
|
||||
import { deleteservice, errorNotify, eventUpdateName, fireUpdateRequest, okNotify, regenport, serviceinfo, serviceregexlist } from '../js/utils';
|
||||
import { BsArrowRepeat } from "react-icons/bs"
|
||||
import { errorNotify, eventUpdateName, fireUpdateRequest, serviceinfo, serviceregexlist } from '../js/utils';
|
||||
import { useWindowEvent } from '@mantine/hooks';
|
||||
|
||||
function ServiceDetails() {
|
||||
@@ -54,58 +51,12 @@ function ServiceDetails() {
|
||||
|
||||
const navigator = useNavigate()
|
||||
|
||||
const [deleteModal, setDeleteModal] = useState(false)
|
||||
const [changePortModal, setChangePortModal] = useState(false)
|
||||
const [tooltipDeleteOpened, setTooltipDeleteOpened] = useState(false);
|
||||
const [tooltipChangeOpened, setTooltipChangeOpened] = useState(false);
|
||||
const [tooltipAddRegexOpened, setTooltipAddRegexOpened] = useState(false);
|
||||
|
||||
const deleteService = () => {
|
||||
deleteservice(serviceInfo.id).then(res => {
|
||||
if (!res){
|
||||
okNotify("Service delete complete!",`The service ${serviceInfo.id} has been deleted!`)
|
||||
updateInfo();
|
||||
}else
|
||||
errorNotify("An error occurred while deleting a service",`Error: ${res}`)
|
||||
}).catch(err => {
|
||||
errorNotify("An error occurred while deleting a service",`Error: ${err}`)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const changePort = () => {
|
||||
regenport(serviceInfo.id).then(res => {
|
||||
if (!res){
|
||||
okNotify("Service port regeneration completed!",`The service ${serviceInfo.id} has changed the internal port!`)
|
||||
updateInfo();
|
||||
}else
|
||||
errorNotify("An error occurred while changing the internal service port",`Error: ${res}`)
|
||||
}).catch(err => {
|
||||
errorNotify("An error occurred while changing the internal service port",`Error: ${err}`)
|
||||
})
|
||||
}
|
||||
const [tooltipAddRegexOpened, setTooltipAddRegexOpened] = useState(false);
|
||||
|
||||
return <div>
|
||||
<LoadingOverlay visible={loader} />
|
||||
<ServiceRow service={serviceInfo} additional_buttons={<>
|
||||
<Tooltip label="Delete service" zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color="red" opened={tooltipDeleteOpened} tooltipId="tooltip-delete-id">
|
||||
<ActionIcon color="red" onClick={()=>setDeleteModal(true)} size="xl" radius="md" variant="filled"
|
||||
aria-describedby="tooltip-delete-id"
|
||||
onFocus={() => setTooltipDeleteOpened(false)} onBlur={() => setTooltipDeleteOpened(false)}
|
||||
onMouseEnter={() => setTooltipDeleteOpened(true)} onMouseLeave={() => setTooltipDeleteOpened(false)}
|
||||
><BsTrashFill size={22} /></ActionIcon>
|
||||
</Tooltip>
|
||||
<Space w="md"/>
|
||||
<Tooltip label="Change proxy port" zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color="blue" opened={tooltipChangeOpened} tooltipId="tooltip-change-id">
|
||||
<ActionIcon color="blue" onClick={()=>setChangePortModal(true)} size="xl" radius="md" variant="filled"
|
||||
aria-describedby="tooltip-change-id"
|
||||
onFocus={() => setTooltipChangeOpened(false)} onBlur={() => setTooltipChangeOpened(false)}
|
||||
onMouseEnter={() => setTooltipChangeOpened(true)} onMouseLeave={() => setTooltipChangeOpened(false)}
|
||||
><BsArrowRepeat size={28} /></ActionIcon>
|
||||
</Tooltip>
|
||||
<Space w="md"/>
|
||||
</>}></ServiceRow>
|
||||
|
||||
<ServiceRow service={serviceInfo} />
|
||||
{regexesList.length === 0?<>
|
||||
<Space h="xl" />
|
||||
<Title className='center-flex' align='center' order={3}>No regex found for this service! Add one by clicking the "+" buttons</Title>
|
||||
@@ -126,20 +77,7 @@ function ServiceDetails() {
|
||||
|
||||
{srv_id?<AddNewRegex opened={open} onClose={closeModal} service={srv_id} />:null}
|
||||
|
||||
<YesNoModal
|
||||
title='Are you sure to delete this service?'
|
||||
description={`You are going to delete the service '${serviceInfo.id}', causing the stopping of the firewall and deleting all the regex associated. This will cause the shutdown of your service! ⚠️`}
|
||||
onClose={()=>setDeleteModal(false) }
|
||||
action={deleteService}
|
||||
opened={deleteModal}
|
||||
/>
|
||||
<YesNoModal
|
||||
title='Are you sure to change the proxy internal port?'
|
||||
description={`You are going to change the proxy port '${serviceInfo.internal_port}'. This will cause the shutdown of your service temporarily! ⚠️`}
|
||||
onClose={()=>setChangePortModal(false)}
|
||||
action={changePort}
|
||||
opened={changePortModal}
|
||||
/>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user