Добавил показ диалогов переход по табам
и показ вывода
This commit is contained in:
parent
19891328fc
commit
a52b9a24cf
@ -1,16 +1,19 @@
|
|||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
import {Table, TableBody, TableCell, TableHead, TableRow, IconButton, Autocomplete, TextField} from "@mui/material";
|
import {Table, TableBody, TableCell, TableHead, TableRow, IconButton, Autocomplete, TextField} from "@mui/material";
|
||||||
import Command, {CommandInterface} from "./elements/command";
|
import Command, {CommandInterface} from "./elements/command";
|
||||||
import {useEffect, useState} from "react";
|
import {useContext, useEffect, useState} from "react";
|
||||||
import PlayCircleOutline from '@mui/icons-material/PlayCircleOutline';
|
import PlayCircleOutline from '@mui/icons-material/PlayCircleOutline';
|
||||||
import { v4 } from "uuid"
|
import ConfirmDialog from "../confirm-dialog";
|
||||||
|
import TabContext from "../../../context/tab";
|
||||||
|
import {TabEnum} from "../../../pages";
|
||||||
|
|
||||||
export default function Commands() {
|
export default function Commands() {
|
||||||
|
const {setTab} = useContext(TabContext)
|
||||||
const [commands, setCommands] = useState<CommandInterface[]>([]);
|
const [commands, setCommands] = useState<CommandInterface[]>([]);
|
||||||
const [selectedCommand, setSelectedCommand] = useState<CommandInterface|null>(null);
|
const [selectedCommand, setSelectedCommand] = useState<CommandInterface|null>(null);
|
||||||
const [command2data, setCommand2data] = useState<Record<string, any>>({});
|
const [command2data, setCommand2data] = useState<Record<string, any>>({});
|
||||||
const [value, setValue] = useState<string | null>('');
|
const [value, setValue] = useState<string | null>('');
|
||||||
let requestId = v4()
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
let refreshCommands = async () => {
|
let refreshCommands = async () => {
|
||||||
let response = await fetch('http://fmw.sipachev.sv/system-monitoring/commands', {
|
let response = await fetch('http://fmw.sipachev.sv/system-monitoring/commands', {
|
||||||
@ -46,7 +49,7 @@ export default function Commands() {
|
|||||||
setCommand2data(temp)
|
setCommand2data(temp)
|
||||||
}
|
}
|
||||||
let lock = false
|
let lock = false
|
||||||
let runCommand = async () => {
|
let runCommand = async (dialogId: string) => {
|
||||||
if (lock) {
|
if (lock) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -56,7 +59,7 @@ export default function Commands() {
|
|||||||
lock = true
|
lock = true
|
||||||
let url = `http://fmw.sipachev.sv/system-monitoring/commands/${selectedCommand.name}/run`
|
let url = `http://fmw.sipachev.sv/system-monitoring/commands/${selectedCommand.name}/run`
|
||||||
let data = command2data[selectedCommand.name] || {}
|
let data = command2data[selectedCommand.name] || {}
|
||||||
data['requestId'] = requestId;
|
data['requestId'] = dialogId;
|
||||||
let response = await fetch(url, {
|
let response = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -66,6 +69,7 @@ export default function Commands() {
|
|||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
});
|
});
|
||||||
lock = false
|
lock = false
|
||||||
|
setTab(TabEnum.Processes)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -95,13 +99,14 @@ export default function Commands() {
|
|||||||
{selectedCommand && <TableRow key={selectedCommand.name}>
|
{selectedCommand && <TableRow key={selectedCommand.name}>
|
||||||
<TableCell><Command command={selectedCommand} callback={callback} /></TableCell>
|
<TableCell><Command command={selectedCommand} callback={callback} /></TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<IconButton onClick={runCommand} aria-label="run">
|
<IconButton onClick={() => setOpen(true)} aria-label="run">
|
||||||
<PlayCircleOutline />
|
<PlayCircleOutline />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>}
|
</TableRow>}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
<ConfirmDialog open={open} text={'$$$'} agreeCallback={runCommand} closeCallback={() => setOpen(false)}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import ErrorOutline from "@mui/icons-material/ErrorOutline"
|
|||||||
import Replay from "@mui/icons-material/Replay"
|
import Replay from "@mui/icons-material/Replay"
|
||||||
import RunCircle from "@mui/icons-material/RunCircle"
|
import RunCircle from "@mui/icons-material/RunCircle"
|
||||||
import {IconButton, LinearProgress, TableContainer, Table, TableBody, TableCell, TableHead, TableRow, TablePagination} from "@mui/material"
|
import {IconButton, LinearProgress, TableContainer, Table, TableBody, TableCell, TableHead, TableRow, TablePagination} from "@mui/material"
|
||||||
import { v4 } from "uuid"
|
import ConfirmDialog from "../confirm-dialog";
|
||||||
|
|
||||||
export interface ProcessExceptionInterface {
|
export interface ProcessExceptionInterface {
|
||||||
message: string,
|
message: string,
|
||||||
@ -56,7 +56,8 @@ export default function Processes() {
|
|||||||
const [processes, setProcesses] = useState<ProcessInterface[]>([]);
|
const [processes, setProcesses] = useState<ProcessInterface[]>([]);
|
||||||
const [page, setPage] = useState<number>(0);
|
const [page, setPage] = useState<number>(0);
|
||||||
const [count, setCount] = useState<number>(0);
|
const [count, setCount] = useState<number>(0);
|
||||||
let requestId = v4()
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const [selectedProcess, setSelectedProcess] = useState<ProcessInterface | null>(null);
|
||||||
|
|
||||||
let refreshLock = false
|
let refreshLock = false
|
||||||
let refreshProcesses = async () => {
|
let refreshProcesses = async () => {
|
||||||
@ -80,6 +81,17 @@ export default function Processes() {
|
|||||||
setCount(Number(response.headers.get('X-Pagination-Count')))
|
setCount(Number(response.headers.get('X-Pagination-Count')))
|
||||||
refreshLock = false
|
refreshLock = false
|
||||||
}
|
}
|
||||||
|
let output = async (process: string) => {
|
||||||
|
let response = await fetch(`http://fmw.sipachev.sv/system-monitoring/processes/${process}/output`,
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'X-Plugin-Token': 'passw0rd',
|
||||||
|
'X-Pagination-Count': '0',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const processes: ProcessInterface[] = await response.json()
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setInterval(() => refreshProcesses(), 1000)
|
const timer = setInterval(() => refreshProcesses(), 1000)
|
||||||
@ -114,8 +126,35 @@ export default function Processes() {
|
|||||||
setPage(page);
|
setPage(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
const repeat = (event: any) => {
|
const openRepeatDialog = (process: ProcessInterface) => {
|
||||||
|
setSelectedProcess(process)
|
||||||
|
setOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
let lock = false
|
||||||
|
const repeat = async (dialogId: string) => {
|
||||||
|
if (lock) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!selectedProcess) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lock = true
|
||||||
|
let url = `http://fmw.sipachev.sv/system-monitoring/processes/${selectedProcess.id}/repeat`
|
||||||
|
let data = {
|
||||||
|
requestId: dialogId
|
||||||
|
}
|
||||||
|
let response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json;charset=utf-8',
|
||||||
|
'X-Plugin-Token': 'passw0rd'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
lock = false
|
||||||
|
setSelectedProcess(null)
|
||||||
|
setOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -156,7 +195,7 @@ export default function Processes() {
|
|||||||
{Status.Error === status(process) && <IconButton title={`Error`} aria-label="Error">
|
{Status.Error === status(process) && <IconButton title={`Error`} aria-label="Error">
|
||||||
<ErrorOutline/>
|
<ErrorOutline/>
|
||||||
</IconButton>}
|
</IconButton>}
|
||||||
{Status.Success === status(process) && <IconButton title={`Success`} aria-label="Success">
|
{Status.Success === status(process) && <IconButton onClick={() => output(process.id)} title={`Success`} aria-label="Success">
|
||||||
<CheckCircleOutline/>
|
<CheckCircleOutline/>
|
||||||
</IconButton>}
|
</IconButton>}
|
||||||
{Status.Running === status(process) && <IconButton title={`Running`} aria-label="Running">
|
{Status.Running === status(process) && <IconButton title={`Running`} aria-label="Running">
|
||||||
@ -170,7 +209,7 @@ export default function Processes() {
|
|||||||
</IconButton>}
|
</IconButton>}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{canRepeat(process) && <IconButton onClick={repeat} title={`Repeat`} aria-label="Repeat">
|
{canRepeat(process) && <IconButton onClick={() => openRepeatDialog(process)} title={`Repeat`} aria-label="Repeat">
|
||||||
<Replay/>
|
<Replay/>
|
||||||
</IconButton>}
|
</IconButton>}
|
||||||
{canKill(process) && <IconButton title={`Kill`} aria-label="Kill">
|
{canKill(process) && <IconButton title={`Kill`} aria-label="Kill">
|
||||||
@ -192,6 +231,10 @@ export default function Processes() {
|
|||||||
page={page}
|
page={page}
|
||||||
onPageChange={handleChangePage}
|
onPageChange={handleChangePage}
|
||||||
/>
|
/>
|
||||||
|
<ConfirmDialog open={open} text={'!!!'} agreeCallback={repeat} closeCallback={() => {
|
||||||
|
setSelectedProcess(null)
|
||||||
|
setOpen(false)
|
||||||
|
}}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
10
context/tab.ts
Normal file
10
context/tab.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export interface ContextInterface {
|
||||||
|
tab: number,
|
||||||
|
setTab: (number: number) => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
const Context = React.createContext({} as ContextInterface)
|
||||||
|
export const Provider = Context.Provider
|
||||||
|
export default Context
|
@ -4,9 +4,15 @@ import Processes from "../components/elements/processes";
|
|||||||
import {Tabs, Tab} from '@mui/material';
|
import {Tabs, Tab} from '@mui/material';
|
||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import Commands from "../components/elements/commands";
|
import Commands from "../components/elements/commands";
|
||||||
|
import {Provider as TabProvider} from '../context/tab'
|
||||||
|
|
||||||
|
export enum TabEnum {
|
||||||
|
Commands,
|
||||||
|
Processes,
|
||||||
|
}
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [tab, setTab] = useState<number>(0);
|
const [tab, setTab] = useState<TabEnum>(TabEnum.Processes);
|
||||||
const handleChange = (event: any, tab: number) => setTab(tab)
|
const handleChange = (event: any, tab: number) => setTab(tab)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -25,11 +31,14 @@ export default function Home() {
|
|||||||
allowScrollButtonsMobile
|
allowScrollButtonsMobile
|
||||||
aria-label="scrollable force tabs example"
|
aria-label="scrollable force tabs example"
|
||||||
>
|
>
|
||||||
<Tab label="Commands" />
|
<Tab value={TabEnum.Commands} label="Commands" />
|
||||||
<Tab label="Processes" />
|
<Tab value={TabEnum.Processes} label="Processes" />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
{tab === 0 && <Commands />}
|
<TabProvider value={{tab, setTab}}>
|
||||||
{tab === 1 && <Processes />}
|
{tab === TabEnum.Commands && <Commands />}
|
||||||
|
{tab === TabEnum.Processes && <Processes />}
|
||||||
|
</TabProvider>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user