import styles from './styles.module.css' import {useContext, useEffect, useState} from "react" import DeleteForeverOutlined from "@mui/icons-material/DeleteForeverOutlined" import StopCircleOutlined from "@mui/icons-material/StopCircleOutlined" import PauseCircleOutline from "@mui/icons-material/PauseCircleOutline" import PlayCircleOutline from "@mui/icons-material/PlayCircleOutline" import HourglassEmptyOutlined from "@mui/icons-material/HourglassEmptyOutlined" import CheckCircleOutline from "@mui/icons-material/CheckCircleOutline" import ErrorOutline from "@mui/icons-material/ErrorOutline" import ReplayOutlined from "@mui/icons-material/ReplayOutlined" import RunCircleOutlined from "@mui/icons-material/RunCircleOutlined" import FactCheckOutlined from "@mui/icons-material/FactCheckOutlined" import ThumbUpAltOutlined from '@mui/icons-material/ThumbUpAltOutlined' import LockOutlined from '@mui/icons-material/LockOutlined'; import LockOpenOutlined from '@mui/icons-material/LockOpenOutlined'; import { Box, TextField, CircularProgress, IconButton, LinearProgress, TableContainer, Table, TableBody, TableCell, TableHead, TableRow, TablePagination, Autocomplete } from "@mui/material" import ConfirmDialog from "../confirm-dialog"; import {ProcessInterface, Status} from "../../../api/sm/responses/processes"; import Command from "../commands/elements/command"; import {CommandInterface} from "../../../api/sm/responses/comamnds"; import Grid from '@mui/material/Grid'; import {useApi} from "../../../hooks/use-api"; import Context from "../../../context/token"; enum Action { Run, Repeat, Stop, Kill, Play, Pause, Approve, Unlock, } export default function Processes() { const {token} = useContext(Context) const [processes, setProcesses] = useState([]); const [commands, setCommands] = useState([]); const [page, setPage] = useState(0); const [count, setCount] = useState(0); const [type, setType] = useState(''); const [name, setName] = useState(''); const [loading, setLoading] = useState(true); const [modalLoading, setModalLoading] = useState(true); const [action, setAction] = useState(null); const [command, setCommand] = useState(null); const [selectedProcess, setSelectedProcess] = useState(null); const [optionList, setOptionList] = useState>({}); const [argumentList, setArgumentList] = useState>({}); const api = useApi() let variants = commands.map((command: CommandInterface, index: number) => command.name); variants.push('') let refreshCommands = async () => { const { data: commands } = await api.useMemory().getCommands() setCommands(commands) } useEffect(() => { refreshCommands() }, []) let refreshLock = false let refreshProcesses = async () => { if (refreshLock) { return } refreshLock = true let data: any = {} if (type && type !== 'None') { data['type'] = type.toLowerCase() } if (!!name) { data['name'] = name } const { data: processes, headers } = await api.getProcesses({ ...data, page: page + 1, limit: 20, }) setProcesses(processes) setCount(Number(headers.get('X-Pagination-Count'))) setLoading(false) refreshLock = false } let output = async (process: ProcessInterface) => { const { data: output } = await api.getProcessOutput({ id: process.id }) let a = document.createElement("a"); let file = new Blob([output], {type: 'plain/text'}); a.href = URL.createObjectURL(file); a.download = `${process.id}.txt`; a.click(); } useEffect(() => { const timer = setInterval(() => refreshProcesses(), 1000) return () => clearInterval(timer); }, [page, name, type]); useEffect(() => { if (action === null) { setSelectedProcess(null) setCommand(null) } }, [action]); let isFinished = (process: ProcessInterface) => process.cancelledAt || process.completedAt let isCancelled = (process: ProcessInterface) => process.cancelledAt let isRunning = (process: ProcessInterface) => process.startedAt && !isFinished(process) const processName = (process: ProcessInterface) => { return process.name + ' ' + JSON.stringify(process.options)+ ' ' + JSON.stringify(process.arguments) } const handleChangePage = (event: any, page: number) => { setPage(page); } const openDialog = (process: ProcessInterface, action: Action) => { setSelectedProcess(process) setAction(action) } let lock = false const agreeCallback = async (dialogId: string) => { if (lock) { return } if (!selectedProcess) { return } lock = true if (action === Action.Run) { await api.runCommand({ commandName: selectedProcess.name, options: optionList, arguments: argumentList, requestId: dialogId, }) } if (action === Action.Approve) { await api.approveProcess({ id: selectedProcess.id, }) } if (action === Action.Unlock) { await api.unlockProcess({ id: selectedProcess.id, }) } if (action === Action.Repeat) { await api.repeatProcess({ id: selectedProcess.id, requestId: dialogId }) } lock = false setAction(null) } let callback = (name: string, optionList: Record, argumentList: Record) => { setOptionList(optionList) setArgumentList(argumentList) } if (loading) { return ( ); } return ( <>
{ setType(newValue || ''); setLoading(true) }} disablePortal options={['None', "Running", "History", "Locked", 'Need_Approve', '']} renderInput={(params) => } /> { setName(newValue || ''); setLoading(true) }} disablePortal options={variants} renderInput={(params) => } /> Name Progress Status Action Created {processes.map((process: ProcessInterface, index: number) => ( {process.name} {!process.progress && !isFinished(process) && isRunning(process) && } {!process.progress && !isFinished(process) && !isRunning(process) && } {!process.progress && isFinished(process) && !isCancelled(process) && } {!process.progress && isFinished(process) && isCancelled(process) && } {process.progress && } {process.progress && {`${process.progress.progress}`} / {`${process.progress.total}`} - {process.progress.percent}% [{process.progress.memory}] / {process.progress.remaining} } {process.canPlay && openDialog(process, Action.Play)} title={`Play`} aria-label="Play"> } {process.canPause && openDialog(process, Action.Pause)} title={`Pause`} aria-label="Pause"> } {process.canStop && openDialog(process, Action.Stop)} title={`Stop`} aria-label="Stop"> } {Status.Error === process.status && } {Status.Success === process.status && } {Status.Running === process.status && } {Status.Cancelled === process.status && } {Status.Wait === process.status && } {process.lock && } {process.canUnlock && token && token?.permissions.indexOf('unlock_process') > -1 && openDialog(process, Action.Unlock)} title={`Unlock`} aria-label="Unlock"> } {process.canApprove && token && token?.permissions.indexOf('approve_process') > -1 && openDialog(process, Action.Approve)} title={`Approve`} aria-label="Approve"> } {process.canRepeat && token && token?.permissions.indexOf('run_command') > -1 && openDialog(process, Action.Repeat)} title={`Repeat`} aria-label="Repeat"> } {process.canKill && token && token?.permissions.indexOf('kill_process') > -1 && openDialog(process, Action.Kill)} title={`Kill`} aria-label="Kill"> } {process?.outputId && output(process)} aria-label="Output"> } {new Date(process.createdAt).toLocaleString()} ))}
{selectedProcess && { setAction(Action.Run) setModalLoading(true) let {data: command} = await api.getCommand(selectedProcess.name) setCommand(command) setModalLoading(false) }} closeCallback={() => {setAction(null)}}> Reply? } {selectedProcess && {setAction(null)}}> {modalLoading && } {!modalLoading && !!command && (Action.Run === action) && } } {selectedProcess && {setAction(null)}}> Approve? } {selectedProcess && {setAction(null)}}> Unlock? } {selectedProcess && -1) } agreeCallback={async () => { Action.Play === action && await api.playProcess(selectedProcess.id) Action.Pause === action && await api.pauseProcess(selectedProcess.id) Action.Stop === action && await api.stopProcess(selectedProcess.id) Action.Kill === action && await api.killProcess(selectedProcess.id) setAction(null) }} closeCallback={() => {setAction(null)}}> {selectedProcess.name} } ) }