feat(frontend): custom cwmp/usp messages templates
This commit is contained in:
parent
55cf6f4310
commit
0d134e1082
|
|
@ -19,37 +19,26 @@ import {
|
|||
DialogContentText,
|
||||
DialogActions,
|
||||
Box,
|
||||
IconButton
|
||||
IconButton,
|
||||
Grid
|
||||
} from '@mui/material';
|
||||
import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
|
||||
import PaperAirplane from '@heroicons/react/24/solid/PaperAirplaneIcon';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Backdrop from '@mui/material/Backdrop';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useBackendContext } from 'src/contexts/backend-context';
|
||||
import DocumentArrowDown from '@heroicons/react/24/outline/DocumentArrowDownIcon';
|
||||
import TrashIcon from '@heroicons/react/24/outline/TrashIcon';
|
||||
import PlusCircleIcon from '@heroicons/react/24/outline/PlusCircleIcon';
|
||||
import EnvelopeIcon from '@heroicons/react/24/outline/EnvelopeIcon';
|
||||
import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
|
||||
|
||||
|
||||
export const DevicesRPC = () => {
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [scroll, setScroll] = useState('paper');
|
||||
const [answer, setAnswer] = useState(false)
|
||||
const [content, setContent] = useState('')
|
||||
const [age, setAge] = useState(2);
|
||||
|
||||
const [value, setValue] = useState(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:GetParameterValues>
|
||||
<ParameterNames>
|
||||
<string>InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.</string>
|
||||
<string>InternetGatewayDevice.LANDevice.1.WLANConfiguration.2.</string>
|
||||
</ParameterNames>
|
||||
</cwmp:GetParameterValues>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`)
|
||||
let { httpRequest } = useBackendContext()
|
||||
|
||||
var prettifyXml = function(sourceXml)
|
||||
{
|
||||
|
|
@ -75,129 +64,219 @@ var prettifyXml = function(sourceXml)
|
|||
return resultXml;
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
const handleOpen = () => {
|
||||
setOpen(true);
|
||||
var myHeaders = new Headers();
|
||||
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||
|
||||
var raw = value
|
||||
|
||||
var requestOptions = {
|
||||
method: 'PUT',
|
||||
headers: myHeaders,
|
||||
body: raw,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
var method;
|
||||
|
||||
switch(age) {
|
||||
case 1:
|
||||
method="addObject"
|
||||
break;
|
||||
case 2:
|
||||
method="getParameterValues"
|
||||
break;
|
||||
case 3:
|
||||
method="setParameterValues"
|
||||
break;
|
||||
case 4:
|
||||
method="deleteObject"
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/cwmp/${router.query.id[0]}/${method}`, requestOptions)
|
||||
.then(response => response.text())
|
||||
.then(result => {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
}
|
||||
setOpen(false)
|
||||
setAnswer(true)
|
||||
let teste = prettifyXml(result)
|
||||
console.log(teste)
|
||||
setContent(teste)
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
};
|
||||
|
||||
const handleChangeRPC = (event) => {
|
||||
setAge(event.target.value);
|
||||
switch(event.target.value) {
|
||||
case 1:
|
||||
setValue(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
const [open, setOpen] = useState(false);
|
||||
const [scroll, setScroll] = useState('paper');
|
||||
const [answer, setAnswer] = useState(false)
|
||||
const [content, setContent] = useState('')
|
||||
const [age, setAge] = useState(6);
|
||||
const [newMessage, setNewMessage] = useState(false)
|
||||
const [message, setMessage] = useState(null)
|
||||
const [currentMsg, setCurrentMsg] = useState(0)
|
||||
const [newMsgName, setNewMsgName] = useState("")
|
||||
const [value, setValue] = useState()
|
||||
const [saveChanges, setSaveChanges] = useState(false)
|
||||
const [loadingSaveMsg, setLoadingSaveMsg] = useState(false)
|
||||
const possibleMsgs = [
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:SetParameterValues>
|
||||
<ParameterList soapenc:arrayType="cwmp:ParameterValueStruct[4]">
|
||||
<ParameterValueStruct>
|
||||
<Name>InternetGatewayDevice.TraceRouteDiagnostics.Host</Name>
|
||||
<Value>192.168.60.4</Value>
|
||||
</ParameterValueStruct>
|
||||
</ParameterList>
|
||||
<ParameterKey></ParameterKey>
|
||||
</cwmp:SetParameterValues>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`,
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:DeleteObject>
|
||||
<ObjectName>InternetGatewayDevice.LANDevice.1.WLANConfiguration.2.</ObjectName>
|
||||
<ParameterKey></ParameterKey>
|
||||
</cwmp:DeleteObject>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`,
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:AddObject>
|
||||
<ObjectName>InternetGatewayDevice.LANDevice.</ObjectName>
|
||||
<ObjectName>InternetGatewayDevice.LANDevice.1.WLANConfiguration.</ObjectName>
|
||||
<ParameterKey></ParameterKey>
|
||||
</cwmp:AddObject>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`)
|
||||
break;
|
||||
case 2:
|
||||
setValue(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
</soap:Envelope>`,
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:Reboot>
|
||||
<CommandKey>
|
||||
007
|
||||
</CommandKey>
|
||||
</cwmp:Reboot>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`,
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..schemaswt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:GetParameterValues>
|
||||
<ParameterNames>
|
||||
<string>InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.</string>
|
||||
<string>InternetGatewayDevice.LANDevice.1.WLANConfiguration.2.</string>
|
||||
<string>InternetGatewayDevice.LANDevice.2.WLANConfiguration.2.</string>
|
||||
<string>InternetGatewayDevice.LANDevice.2.WLANConfiguration.1.</string>
|
||||
</ParameterNames>
|
||||
</cwmp:GetParameterValues>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`)
|
||||
break;
|
||||
case 3:
|
||||
setValue(`
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
</soap:Envelope>`,`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:SetParameterValues>
|
||||
<ParameterList soapenc:arrayType="cwmp:ParameterValueStruct[3]">
|
||||
<ParameterValueStruct>
|
||||
<Name>InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.Enable</Name>
|
||||
<Value>0</Value>
|
||||
</ParameterValueStruct>
|
||||
<ParameterValueStruct>
|
||||
<Name>InternetGatewayDevice.LANDevice.1.WLANConfiguration.2.SSID</Name>
|
||||
<Value>HUAWEI_TEST-2</Value>
|
||||
</ParameterValueStruct>
|
||||
</ParameterList>
|
||||
<ParameterKey>LC1309123</ParameterKey>
|
||||
</cwmp:SetParameterValues>
|
||||
<cwmp:GetParameterNames>
|
||||
<ParameterPath>InternetGatewayDevice.</ParameterPath>
|
||||
<NextLevel>1</NextLevel>
|
||||
</cwmp:GetParameterNames>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`)
|
||||
break;
|
||||
case 4:
|
||||
setValue(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
</soap:Envelope>`,
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:schemaLocation="urn:dslforum-org:cwmp-1-0 ..\schemas\wt121.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soap:Header/>
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<cwmp:DeleteObject>
|
||||
<ObjectName>InternetGatewayDevice.LANDevice.3.</ObjectName>
|
||||
<ParameterKey></ParameterKey>
|
||||
</cwmp:DeleteObject>
|
||||
<cwmp:GetParameterAttributes>
|
||||
<ParameterNames>
|
||||
<string>InternetGatewayDevice.LANDevice.1.WLANConfiguration.</string>
|
||||
</ParameterNames>
|
||||
</cwmp:GetParameterAttributes>
|
||||
</soap:Body>
|
||||
</soap:Envelope>`)
|
||||
break;
|
||||
default:
|
||||
// code block
|
||||
</soap:Envelope>`]
|
||||
const [newMsgValue, setNewMsgValue] = useState(possibleMsgs[age-1])
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleNewMessageValue = (event) => {
|
||||
setNewMsgValue(event.target.value)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleCancelNewMsgTemplate = () => {
|
||||
setNewMessage(false)
|
||||
setNewMsgName("")
|
||||
setNewMsgValue(possibleMsgs[age-1])
|
||||
// setValue(possibleMsgs[age-1])
|
||||
}
|
||||
|
||||
const saveMsg = async () => {
|
||||
let {status} = await httpRequest(
|
||||
`/api/device/message?name=`+message[currentMsg].name,
|
||||
"PUT",
|
||||
value,
|
||||
null,
|
||||
)
|
||||
if ( status === 204){
|
||||
setSaveChanges(false)
|
||||
setMessage(message.map((msg, index) => {
|
||||
if (index === currentMsg) {
|
||||
return {...msg, value: value}
|
||||
}else{
|
||||
return msg
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
const createNewMsg = async () => {
|
||||
setLoading(true)
|
||||
let {status} = await httpRequest(
|
||||
`/api/device/message/cwmp?name=`+newMsgName,
|
||||
"POST",
|
||||
newMsgValue,
|
||||
null,
|
||||
)
|
||||
if ( status === 204){
|
||||
setNewMessage(false)
|
||||
setNewMsgName("")
|
||||
let result = await fetchMessages()
|
||||
if (result) {
|
||||
setCurrentMsg(result.length-1)
|
||||
}
|
||||
setValue(newMsgValue)
|
||||
setNewMsgValue(possibleMsgs[age-1])
|
||||
}
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
const handleChangeMessage = (event) => {
|
||||
setSaveChanges(false)
|
||||
setCurrentMsg(event.target.value)
|
||||
setValue(message[event.target.value].value)
|
||||
}
|
||||
|
||||
const handleDeleteMessage = async () => {
|
||||
let {status} = await httpRequest(
|
||||
`/api/device/message?name=`+message[currentMsg].name.replace(" ", '+'),
|
||||
"DELETE",
|
||||
)
|
||||
if ( status === 204){
|
||||
fetchMessages()
|
||||
setCurrentMsg(0)
|
||||
setValue("")
|
||||
}
|
||||
}
|
||||
|
||||
const handleOpen = async () => {
|
||||
setOpen(true);
|
||||
|
||||
let {result, status} = await httpRequest(
|
||||
`/api/device/cwmp/${router.query.id[0]}/generic`,
|
||||
"PUT",
|
||||
value,
|
||||
null,
|
||||
"text",
|
||||
)
|
||||
if (status === 200){
|
||||
setAnswer(true)
|
||||
console.log("result:",result)
|
||||
let answer = prettifyXml(result)
|
||||
if (answer == "null"){
|
||||
answer = result
|
||||
}
|
||||
console.log(answer)
|
||||
setContent(answer)
|
||||
}
|
||||
setOpen(false)
|
||||
|
||||
}
|
||||
|
||||
const fetchMessages = async () => {
|
||||
let {result, status} = await httpRequest(
|
||||
`/api/device/message?type=cwmp`,
|
||||
"GET",
|
||||
null,
|
||||
null,
|
||||
)
|
||||
if ( status === 200){
|
||||
setMessage(result)
|
||||
setValue(result ? result[0].value : "")
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
const handleChangeRPC = (event) => {
|
||||
setAge(event.target.value);
|
||||
setNewMsgValue(possibleMsgs[event.target.value-1])
|
||||
};
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValue(event.target.value);
|
||||
};
|
||||
const handleEditMessage = (event) => {
|
||||
setSaveChanges(true)
|
||||
setValue(event.target.value)
|
||||
}
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(event) => {
|
||||
|
|
@ -206,47 +285,83 @@ const handleOpen = () => {
|
|||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchMessages();
|
||||
},[]);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Card>
|
||||
<CardActions sx={{ justifyContent: 'flex-end'}}>
|
||||
<FormControl sx={{width:'100px'}}>
|
||||
<Select
|
||||
labelId="demo-simple-select-standard-label"
|
||||
id="demo-simple-select-standard"
|
||||
value={age}
|
||||
label="Action"
|
||||
onChange={(event)=>{handleChangeRPC(event)}}
|
||||
variant='standard'
|
||||
<CardHeader sx={{ justifyContent: 'flex-end'}}
|
||||
avatar={<SvgIcon>< EnvelopeIcon/></SvgIcon>}
|
||||
title="Custom Message"
|
||||
action={
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-end"}>
|
||||
<Button sx={{ backgroundColor: "rgba(48, 109, 111, 0.04)" }}
|
||||
endIcon={<SvgIcon><PlusCircleIcon /></SvgIcon>}
|
||||
onClick={()=>{setNewMessage(true)}}
|
||||
>
|
||||
<MenuItem value={1}>Create</MenuItem>
|
||||
<MenuItem value={2}>Read</MenuItem>
|
||||
<MenuItem value={3}>Update</MenuItem>
|
||||
<MenuItem value={4}>Delete</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</CardActions>
|
||||
<Stack direction={"row"} spacing={1}>
|
||||
New Message
|
||||
</Stack>
|
||||
</Button>
|
||||
</Stack>}
|
||||
>
|
||||
</CardHeader>
|
||||
<Divider />
|
||||
<CardContent>
|
||||
<Stack pb={4} spacing={5} direction={"row"}>
|
||||
<FormControl sx={{display:"flex", width: "15%"}} variant="standard" >
|
||||
<InputLabel>Message</InputLabel>
|
||||
<Select
|
||||
value={currentMsg}
|
||||
onChange={(event)=>{handleChangeMessage(event)}}
|
||||
>
|
||||
{message && message.map((msg, index) => {
|
||||
return <MenuItem value={index}>{msg.name}</MenuItem>
|
||||
})}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
<Stack
|
||||
spacing={3}
|
||||
alignItems={'stretch'}
|
||||
>
|
||||
<TextField
|
||||
{!loadingSaveMsg ? <TextField
|
||||
id="outlined-multiline-static"
|
||||
size="large"
|
||||
multiline="true"
|
||||
label="Mensagem"
|
||||
// label="Payload"
|
||||
name="password"
|
||||
onChange={handleChange}
|
||||
onChange={handleEditMessage}
|
||||
value={value}
|
||||
variant="filled"
|
||||
fullWidth
|
||||
rows="15"
|
||||
/>
|
||||
/>:<CircularProgress />}
|
||||
</Stack>
|
||||
</CardContent>
|
||||
<Divider />
|
||||
<CardActions sx={{ justifyContent: 'flex-end' }}>
|
||||
{/* <Divider /> */}
|
||||
<CardActions>
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-start"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><TrashIcon /></SvgIcon>}
|
||||
onClick={handleDeleteMessage}
|
||||
disabled={!message}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
{!loadingSaveMsg ? <Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><DocumentArrowDown /></SvgIcon>}
|
||||
onClick={saveMsg}
|
||||
disabled={!saveChanges}
|
||||
>
|
||||
Save
|
||||
</Button>: <CircularProgress />}
|
||||
</Stack>
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-end"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><PaperAirplane /></SvgIcon>}
|
||||
|
|
@ -254,6 +369,7 @@ const handleOpen = () => {
|
|||
>
|
||||
Send
|
||||
</Button>
|
||||
</Stack>
|
||||
</CardActions>
|
||||
<Backdrop
|
||||
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
|
||||
|
|
@ -307,6 +423,83 @@ const handleOpen = () => {
|
|||
}}>Ok</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<Dialog open={newMessage} maxWidth={"800px"}>
|
||||
<DialogTitle>
|
||||
<SvgIcon><EnvelopeIcon/></SvgIcon>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Stack
|
||||
direction={"row"}
|
||||
container
|
||||
pb={3}
|
||||
// direction="column"
|
||||
// alignItems="center"
|
||||
// justifyContent="center"
|
||||
pt={1}
|
||||
spacing={3}
|
||||
>
|
||||
<TextField
|
||||
variant='standard'
|
||||
fullWidth
|
||||
value={newMsgName}
|
||||
onChange={(event)=>{setNewMsgName(event.target.value)}}
|
||||
label="Name"
|
||||
sx={{maxWidth: "30%", justifyContent:"center"}}
|
||||
/>
|
||||
<FormControl sx={{display:"flex", width: "30%"}} variant="standard" >
|
||||
<InputLabel>Template</InputLabel>
|
||||
<Select
|
||||
value={age}
|
||||
label="Action"
|
||||
name='action'
|
||||
onChange={(event)=>{handleChangeRPC(event)}}
|
||||
>
|
||||
<MenuItem value={1}>SetParameterValues</MenuItem>
|
||||
<MenuItem value={2}>DeleteObject</MenuItem>
|
||||
<MenuItem value={3}>AddObject</MenuItem>
|
||||
<MenuItem value={4}>Reboot</MenuItem>
|
||||
<MenuItem value={5}>GetParameterValues</MenuItem>
|
||||
<MenuItem value={6}>GetParameterNames</MenuItem>
|
||||
<MenuItem value={7}>GetParameterAttributes</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
<Stack
|
||||
spacing={3}
|
||||
alignItems={'stretch'}
|
||||
width={"600px"}
|
||||
>
|
||||
<TextField
|
||||
id="outlined-multiline-static"
|
||||
size="large"
|
||||
multiline="true"
|
||||
label="Payload"
|
||||
name="password"
|
||||
onChange={handleNewMessageValue}
|
||||
value={newMsgValue}
|
||||
// fullWidth
|
||||
// rows="15"
|
||||
/>
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
{/* <Divider/> */}
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-end"} p={2}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleCancelNewMsgTemplate}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
{!loading ?
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><CheckIcon /></SvgIcon>}
|
||||
onClick={createNewMsg}
|
||||
>
|
||||
Save
|
||||
</Button>:<CircularProgress />}
|
||||
</Stack>
|
||||
</Dialog>
|
||||
</Card>
|
||||
</form>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,91 +19,90 @@ import {
|
|||
DialogContentText,
|
||||
DialogActions,
|
||||
Box,
|
||||
IconButton
|
||||
IconButton,
|
||||
Grid
|
||||
} from '@mui/material';
|
||||
import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
|
||||
import PaperAirplane from '@heroicons/react/24/solid/PaperAirplaneIcon';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Backdrop from '@mui/material/Backdrop';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useBackendContext } from 'src/contexts/backend-context';
|
||||
import DocumentArrowDown from '@heroicons/react/24/outline/DocumentArrowDownIcon';
|
||||
import TrashIcon from '@heroicons/react/24/outline/TrashIcon';
|
||||
import PlusCircleIcon from '@heroicons/react/24/outline/PlusCircleIcon';
|
||||
import EnvelopeIcon from '@heroicons/react/24/outline/EnvelopeIcon';
|
||||
import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
|
||||
|
||||
|
||||
export const DevicesRPC = () => {
|
||||
|
||||
const router = useRouter()
|
||||
let { httpRequest } = useBackendContext()
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [scroll, setScroll] = useState('paper');
|
||||
const [answer, setAnswer] = useState(false)
|
||||
const [content, setContent] = useState('')
|
||||
const [age, setAge] = useState(2);
|
||||
|
||||
const [value, setValue] = useState(`{
|
||||
"param_paths": [
|
||||
"Device.WiFi.SSID.[Name==wlan0].",
|
||||
"Device.IP.Interface.*.Alias",
|
||||
"Device.DeviceInfo.FirmwareImage.*.Alias",
|
||||
"Device.IP.Interface.1.IPv4Address.1.IPAddress"
|
||||
],
|
||||
"max_depth": 2
|
||||
}`)
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
const handleOpen = () => {
|
||||
setOpen(true);
|
||||
var myHeaders = new Headers();
|
||||
myHeaders.append("Content-Type", "application/json");
|
||||
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||
|
||||
var raw = value
|
||||
|
||||
var requestOptions = {
|
||||
method: 'PUT',
|
||||
headers: myHeaders,
|
||||
body: raw,
|
||||
redirect: 'follow'
|
||||
};
|
||||
|
||||
var method;
|
||||
|
||||
switch(age) {
|
||||
case 1:
|
||||
method="add"
|
||||
break;
|
||||
case 2:
|
||||
method="get"
|
||||
break;
|
||||
case 3:
|
||||
method="set"
|
||||
break;
|
||||
case 4:
|
||||
method="del"
|
||||
break;
|
||||
const [age, setAge] = useState(6);
|
||||
const [newMessage, setNewMessage] = useState(false)
|
||||
const [message, setMessage] = useState(null)
|
||||
const [currentMsg, setCurrentMsg] = useState(0)
|
||||
const [newMsgName, setNewMsgName] = useState("")
|
||||
const [value, setValue] = useState()
|
||||
const [saveChanges, setSaveChanges] = useState(false)
|
||||
const [loadingSaveMsg, setLoadingSaveMsg] = useState(false)
|
||||
const possibleMsgs = [
|
||||
`{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 4
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"set": {
|
||||
"allow_partial":true,
|
||||
"update_objs":[
|
||||
{
|
||||
"obj_path":"Device.IP.Interface.1.",
|
||||
"param_settings":[
|
||||
{
|
||||
"param":"Alias",
|
||||
"value":"test",
|
||||
"required":true
|
||||
}
|
||||
|
||||
|
||||
fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device/${router.query.id[0]}/any/${method}`, requestOptions)
|
||||
.then(response => response.text())
|
||||
.then(result => {
|
||||
if (result.status === 401){
|
||||
router.push("/auth/login")
|
||||
]
|
||||
}
|
||||
setOpen(false)
|
||||
setAnswer(true)
|
||||
let teste = JSON.stringify(JSON.parse(result), null, 2)
|
||||
console.log(teste)
|
||||
setContent(teste)
|
||||
})
|
||||
.catch(error => console.log('error', error));
|
||||
};
|
||||
|
||||
const handleChangeRPC = (event) => {
|
||||
setAge(event.target.value);
|
||||
switch(event.target.value) {
|
||||
case 1:
|
||||
setValue(`{
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 10
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"delete": {
|
||||
"allow_partial": true,
|
||||
"obj_paths": [
|
||||
"Device.IP.Interface.[Alias==test]."
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`
|
||||
{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 8
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"add": {
|
||||
"allow_partial": true,
|
||||
"create_objs": [
|
||||
{
|
||||
|
|
@ -117,53 +116,199 @@ const handleOpen = () => {
|
|||
]
|
||||
}
|
||||
]
|
||||
}`)
|
||||
break;
|
||||
case 2:
|
||||
setValue(`{
|
||||
"param_paths": [
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 6
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"operate": {
|
||||
"command": "Device.Reboot()",
|
||||
"send_resp": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 1
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"get": {
|
||||
"paramPaths": [
|
||||
"Device.WiFi.SSID.[Name==wlan0].",
|
||||
"Device.IP.Interface.*.Alias",
|
||||
"Device.DeviceInfo.FirmwareImage.*.Alias",
|
||||
"Device.IP.Interface.1.IPv4Address.1.IPAddress"
|
||||
],
|
||||
"max_depth": 2
|
||||
}`)
|
||||
break;
|
||||
case 3:
|
||||
setValue(`
|
||||
{
|
||||
"allow_partial":true,
|
||||
"update_objs":[
|
||||
{
|
||||
"obj_path":"Device.IP.Interface.[Alias==pamonha].",
|
||||
"param_settings":[
|
||||
{
|
||||
"param":"Alias",
|
||||
"value":"goiaba",
|
||||
"required":true
|
||||
"maxDepth": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}`)
|
||||
break;
|
||||
case 4:
|
||||
setValue(`{
|
||||
"allow_partial": true,
|
||||
"obj_paths": [
|
||||
"Device.IP.Interface.3."
|
||||
]
|
||||
}`)
|
||||
break;
|
||||
default:
|
||||
// code block
|
||||
}
|
||||
}`,`{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 12
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"get_supported_dm": {
|
||||
"obj_paths" : [
|
||||
"Device."
|
||||
],
|
||||
"first_level_only" : false,
|
||||
"return_commands" : false,
|
||||
"return_events" : false,
|
||||
"return_params" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`{
|
||||
"header": {
|
||||
"msg_id": "b7dc38ea-aefb-4761-aa55-edaa97adb2f0",
|
||||
"msg_type": 14
|
||||
},
|
||||
"body": {
|
||||
"request": {
|
||||
"get_instances": {
|
||||
"obj_paths" : ["Device.DeviceInfo."],
|
||||
"first_level_only" : false
|
||||
}
|
||||
}
|
||||
}
|
||||
}`]
|
||||
const [newMsgValue, setNewMsgValue] = useState(possibleMsgs[age-1])
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleNewMessageValue = (event) => {
|
||||
setNewMsgValue(event.target.value)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleCancelNewMsgTemplate = () => {
|
||||
setNewMessage(false)
|
||||
setNewMsgName("")
|
||||
setNewMsgValue(possibleMsgs[age-1])
|
||||
// setValue(possibleMsgs[age-1])
|
||||
}
|
||||
|
||||
const saveMsg = async () => {
|
||||
let {status} = await httpRequest(
|
||||
`/api/device/message?name=`+message[currentMsg].name,
|
||||
"PUT",
|
||||
value,
|
||||
null,
|
||||
)
|
||||
if ( status === 204){
|
||||
setSaveChanges(false)
|
||||
setMessage(message.map((msg, index) => {
|
||||
if (index === currentMsg) {
|
||||
return {...msg, value: value}
|
||||
}else{
|
||||
return msg
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
const createNewMsg = async () => {
|
||||
setLoading(true)
|
||||
let {status} = await httpRequest(
|
||||
`/api/device/message/usp?name=`+newMsgName,
|
||||
"POST",
|
||||
newMsgValue,
|
||||
null,
|
||||
)
|
||||
if ( status === 204){
|
||||
setNewMessage(false)
|
||||
setNewMsgName("")
|
||||
let result = await fetchMessages()
|
||||
if (result) {
|
||||
setCurrentMsg(result.length-1)
|
||||
}
|
||||
setValue(newMsgValue)
|
||||
setNewMsgValue(possibleMsgs[age-1])
|
||||
}
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
const handleChangeMessage = (event) => {
|
||||
setSaveChanges(false)
|
||||
setCurrentMsg(event.target.value)
|
||||
setValue(message[event.target.value].value)
|
||||
}
|
||||
|
||||
const handleDeleteMessage = async () => {
|
||||
let {status} = await httpRequest(
|
||||
`/api/device/message?name=`+message[currentMsg].name.replace(" ", '+'),
|
||||
"DELETE",
|
||||
)
|
||||
if ( status === 204){
|
||||
fetchMessages()
|
||||
setCurrentMsg(0)
|
||||
setValue("")
|
||||
}
|
||||
}
|
||||
|
||||
const handleOpen = async () => {
|
||||
setOpen(true);
|
||||
|
||||
let {result, status} = await httpRequest(
|
||||
`/api/device/${router.query.id[0]}/any/generic`,
|
||||
"PUT",
|
||||
value,
|
||||
null,
|
||||
)
|
||||
if (status === 200){
|
||||
setAnswer(true)
|
||||
console.log("result:",result)
|
||||
let answer = JSON.stringify(result, null, 2)
|
||||
if (answer == "null"){
|
||||
answer = result
|
||||
}
|
||||
console.log(answer)
|
||||
setContent(answer)
|
||||
}
|
||||
setOpen(false)
|
||||
|
||||
}
|
||||
|
||||
const fetchMessages = async () => {
|
||||
let {result, status} = await httpRequest(
|
||||
`/api/device/message?type=usp`,
|
||||
"GET",
|
||||
null,
|
||||
null,
|
||||
)
|
||||
if ( status === 200){
|
||||
setMessage(result)
|
||||
setValue(result ? result[0].value : "")
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
const handleChangeRPC = (event) => {
|
||||
setAge(event.target.value);
|
||||
setNewMsgValue(possibleMsgs[event.target.value-1])
|
||||
};
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValue(event.target.value);
|
||||
};
|
||||
const handleEditMessage = (event) => {
|
||||
if (message) {
|
||||
setSaveChanges(true)
|
||||
}
|
||||
setValue(event.target.value)
|
||||
}
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(event) => {
|
||||
|
|
@ -172,47 +317,83 @@ const handleOpen = () => {
|
|||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchMessages();
|
||||
},[]);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Card>
|
||||
<CardActions sx={{ justifyContent: 'flex-end'}}>
|
||||
<FormControl sx={{width:'100px'}}>
|
||||
<Select
|
||||
labelId="demo-simple-select-standard-label"
|
||||
id="demo-simple-select-standard"
|
||||
value={age}
|
||||
label="Action"
|
||||
onChange={(event)=>{handleChangeRPC(event)}}
|
||||
variant='standard'
|
||||
<CardHeader sx={{ justifyContent: 'flex-end'}}
|
||||
avatar={<SvgIcon>< EnvelopeIcon/></SvgIcon>}
|
||||
title="Custom Message"
|
||||
action={
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-end"}>
|
||||
<Button sx={{ backgroundColor: "rgba(48, 109, 111, 0.04)" }}
|
||||
endIcon={<SvgIcon><PlusCircleIcon /></SvgIcon>}
|
||||
onClick={()=>{setNewMessage(true)}}
|
||||
>
|
||||
<MenuItem value={1}>Create</MenuItem>
|
||||
<MenuItem value={2}>Read</MenuItem>
|
||||
<MenuItem value={3}>Update</MenuItem>
|
||||
<MenuItem value={4}>Delete</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</CardActions>
|
||||
<Stack direction={"row"} spacing={1}>
|
||||
New Message
|
||||
</Stack>
|
||||
</Button>
|
||||
</Stack>}
|
||||
>
|
||||
</CardHeader>
|
||||
<Divider />
|
||||
<CardContent>
|
||||
<Stack pb={4} spacing={5} direction={"row"}>
|
||||
<FormControl sx={{display:"flex", width: "15%"}} variant="standard" >
|
||||
<InputLabel>Message</InputLabel>
|
||||
<Select
|
||||
value={currentMsg}
|
||||
onChange={(event)=>{handleChangeMessage(event)}}
|
||||
>
|
||||
{message && message.map((msg, index) => {
|
||||
return <MenuItem value={index}>{msg.name}</MenuItem>
|
||||
})}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
<Stack
|
||||
spacing={3}
|
||||
alignItems={'stretch'}
|
||||
>
|
||||
<TextField
|
||||
{!loadingSaveMsg ? <TextField
|
||||
id="outlined-multiline-static"
|
||||
size="large"
|
||||
multiline="true"
|
||||
label="Mensagem"
|
||||
// label="Payload"
|
||||
name="password"
|
||||
onChange={handleChange}
|
||||
onChange={handleEditMessage}
|
||||
value={value}
|
||||
variant="filled"
|
||||
fullWidth
|
||||
rows="15"
|
||||
/>
|
||||
/>:<CircularProgress />}
|
||||
</Stack>
|
||||
</CardContent>
|
||||
<Divider />
|
||||
<CardActions sx={{ justifyContent: 'flex-end' }}>
|
||||
{/* <Divider /> */}
|
||||
<CardActions>
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-start"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><TrashIcon /></SvgIcon>}
|
||||
onClick={handleDeleteMessage}
|
||||
disabled={!message}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
{!loadingSaveMsg ? <Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><DocumentArrowDown /></SvgIcon>}
|
||||
onClick={saveMsg}
|
||||
disabled={!saveChanges}
|
||||
>
|
||||
Save
|
||||
</Button>: <CircularProgress />}
|
||||
</Stack>
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-end"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><PaperAirplane /></SvgIcon>}
|
||||
|
|
@ -220,6 +401,7 @@ const handleOpen = () => {
|
|||
>
|
||||
Send
|
||||
</Button>
|
||||
</Stack>
|
||||
</CardActions>
|
||||
<Backdrop
|
||||
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
|
||||
|
|
@ -273,6 +455,83 @@ const handleOpen = () => {
|
|||
}}>Ok</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<Dialog open={newMessage} maxWidth={"800px"}>
|
||||
<DialogTitle>
|
||||
<SvgIcon><EnvelopeIcon/></SvgIcon>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Stack
|
||||
direction={"row"}
|
||||
container
|
||||
pb={3}
|
||||
// direction="column"
|
||||
// alignItems="center"
|
||||
// justifyContent="center"
|
||||
pt={1}
|
||||
spacing={3}
|
||||
>
|
||||
<TextField
|
||||
variant='standard'
|
||||
fullWidth
|
||||
value={newMsgName}
|
||||
onChange={(event)=>{setNewMsgName(event.target.value)}}
|
||||
label="Name"
|
||||
sx={{maxWidth: "30%", justifyContent:"center"}}
|
||||
/>
|
||||
<FormControl sx={{display:"flex", width: "30%"}} variant="standard" >
|
||||
<InputLabel>Template</InputLabel>
|
||||
<Select
|
||||
value={age}
|
||||
label="Action"
|
||||
name='action'
|
||||
onChange={(event)=>{handleChangeRPC(event)}}
|
||||
>
|
||||
<MenuItem value={1}>Set</MenuItem>
|
||||
<MenuItem value={2}>Delete</MenuItem>
|
||||
<MenuItem value={3}>Add</MenuItem>
|
||||
<MenuItem value={4}>Operate</MenuItem>
|
||||
<MenuItem value={5}>Get</MenuItem>
|
||||
<MenuItem value={6}>Get Supported DM</MenuItem>
|
||||
<MenuItem value={7}>Get Instances</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
<Stack
|
||||
spacing={3}
|
||||
alignItems={'stretch'}
|
||||
width={"600px"}
|
||||
>
|
||||
<TextField
|
||||
id="outlined-multiline-static"
|
||||
size="large"
|
||||
multiline="true"
|
||||
label="Payload"
|
||||
name="password"
|
||||
onChange={handleNewMessageValue}
|
||||
value={newMsgValue}
|
||||
// fullWidth
|
||||
// rows="15"
|
||||
/>
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
{/* <Divider/> */}
|
||||
<Stack direction={"row"} spacing={1} width={"100%"} justifyContent={"flex-end"} p={2}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleCancelNewMsgTemplate}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
{!loading ?
|
||||
<Button
|
||||
variant="contained"
|
||||
endIcon={<SvgIcon><CheckIcon /></SvgIcon>}
|
||||
onClick={createNewMsg}
|
||||
>
|
||||
Save
|
||||
</Button>:<CircularProgress />}
|
||||
</Stack>
|
||||
</Dialog>
|
||||
</Card>
|
||||
</form>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user