diff --git a/components/elements/commands/index.tsx b/components/elements/commands/index.tsx index 9d18234..e2a00ff 100644 --- a/components/elements/commands/index.tsx +++ b/components/elements/commands/index.tsx @@ -2,10 +2,12 @@ import {Table, TableBody, TableCell, TableHead, TableRow, IconButton} from "@mui import Command, {CommandInterface} from "./elements/command"; import {useEffect, useState} from "react"; import PlayCircleOutline from '@mui/icons-material/PlayCircleOutline'; +import { v4 } from "uuid" export default function Commands() { const [commands, setCommands] = useState([]); const [command2data, setCommand2data] = useState>({}); + let requestId = v4() let refreshCommands = async () => { let response = await fetch('http://fmw.sipachev.sv/system-monitoring/commands', { @@ -17,7 +19,6 @@ export default function Commands() { }); const commands: CommandInterface[] = await response.json() setCommands(commands) - setTimeout(() => refreshCommands, 1000) } useEffect(() => { @@ -44,10 +45,15 @@ export default function Commands() { } setCommand2data(temp) } + let lock = false let runCommand = async () => { + if (lock) { + return + } + lock = true let url = `http://fmw.sipachev.sv/system-monitoring/commands/${command.name}/run` let data = command2data[command.name] || {} - data['requestId'] = '123'; + data['requestId'] = requestId; let response = await fetch(url, { method: 'POST', headers: { @@ -56,6 +62,7 @@ export default function Commands() { }, body: JSON.stringify(data) }); + lock = false } return ( diff --git a/components/elements/processes/index.tsx b/components/elements/processes/index.tsx index 701116f..6c72380 100644 --- a/components/elements/processes/index.tsx +++ b/components/elements/processes/index.tsx @@ -1,15 +1,16 @@ import styles from './styles.module.css' -import {useEffect, useState} from "react"; -import DeleteForever from "@mui/icons-material/DeleteForever"; -import StopCircle from "@mui/icons-material/StopCircle"; -import PauseCircleOutline from "@mui/icons-material/PauseCircleOutline"; -import PlayCircleOutline from "@mui/icons-material/PlayCircleOutline"; -import HourglassEmpty from "@mui/icons-material/HourglassEmpty"; -import CheckCircleOutline from "@mui/icons-material/CheckCircleOutline"; -import ErrorOutline from "@mui/icons-material/ErrorOutline"; -import Replay from "@mui/icons-material/Replay"; -import RunCircle from "@mui/icons-material/RunCircle"; -import {IconButton, LinearProgress, TableContainer, Table, TableBody, TableCell, TableHead, TableRow, TablePagination} from "@mui/material"; +import {useEffect, useState} from "react" +import DeleteForever from "@mui/icons-material/DeleteForever" +import StopCircle from "@mui/icons-material/StopCircle" +import PauseCircleOutline from "@mui/icons-material/PauseCircleOutline" +import PlayCircleOutline from "@mui/icons-material/PlayCircleOutline" +import HourglassEmpty from "@mui/icons-material/HourglassEmpty" +import CheckCircleOutline from "@mui/icons-material/CheckCircleOutline" +import ErrorOutline from "@mui/icons-material/ErrorOutline" +import Replay from "@mui/icons-material/Replay" +import RunCircle from "@mui/icons-material/RunCircle" +import {IconButton, LinearProgress, TableContainer, Table, TableBody, TableCell, TableHead, TableRow, TablePagination} from "@mui/material" +import { v4 } from "uuid" export interface ProcessExceptionInterface { message: string, @@ -55,8 +56,14 @@ export default function Processes() { const [processes, setProcesses] = useState([]); const [page, setPage] = useState(0); const [count, setCount] = useState(0); + let requestId = v4() + let refreshLock = false let refreshProcesses = async () => { + if (refreshLock) { + return + } + refreshLock = true let response = await fetch('http://fmw.sipachev.sv/system-monitoring/processes?' + new URLSearchParams({ page: page + 1, limit: 20, @@ -71,12 +78,13 @@ export default function Processes() { const processes: ProcessInterface[] = await response.json() setProcesses(processes) setCount(Number(response.headers.get('X-Pagination-Count'))) - setTimeout(() => refreshProcesses, 1000) + refreshLock = false } useEffect(() => { - refreshProcesses() - }, [page]) + const timer = setInterval(() => refreshProcesses(), 1000) + return () => clearInterval(timer); + }, [page]); let isFinished = (process: ProcessInterface) => process.cancelledAt || process.completedAt let canPlay = (process: ProcessInterface) => !isFinished(process) && process.progress && process.pausedAt @@ -106,6 +114,10 @@ export default function Processes() { setPage(page); } + const repeat = (event: any) => { + + } + return ( <> @@ -158,7 +170,7 @@ export default function Processes() { } - {canRepeat(process) && + {canRepeat(process) && } {canKill(process) && diff --git a/package.json b/package.json index f0def90..8062849 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "react-dom": "18.2.0", "styled-components": "^5.3.6", "tailwindcss": "^3.2.4", - "typescript": "4.9.4" + "typescript": "4.9.4", + "uuid": "^9.0.0" } } diff --git a/yarn.lock b/yarn.lock index 7180db0..9a4a6a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2837,6 +2837,11 @@ util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"